-
-
Save rolfbjarne/1115b3e1aa14ee7acfd2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
using ObjCRuntime; | |
using UIKit; | |
using runtime; | |
namespace hook | |
{ | |
public static class Hook | |
{ | |
[DllImport("/usr/lib/libobjc.dylib")] | |
private static extern IntPtr class_getInstanceMethod(IntPtr classHandle, IntPtr Selector); | |
[DllImport("/usr/lib/libobjc.dylib")] | |
private static extern IntPtr method_getImplementation(IntPtr method); | |
[DllImport("/usr/lib/libobjc.dylib")] | |
private static extern void method_setImplementation(IntPtr method, IntPtr imp); | |
[DllImport ("/usr/lib/libobjc.dylib")] | |
internal static extern IntPtr object_getClass (IntPtr obj); | |
[MonoNativeFunctionWrapper] | |
private delegate IntPtr PopDelegate(IntPtr self, IntPtr sel, bool animated); | |
private static IntPtr OrigPopImpl; | |
static PopDelegate popDelegate; | |
public static void Setup () | |
{ | |
var classHandle = Class.GetHandle("UINavigationController"); | |
var selector = Selector.GetHandle("popViewControllerAnimated:"); | |
var method = class_getInstanceMethod(classHandle, selector); | |
OrigPopImpl = method_getImplementation (method); | |
popDelegate = PopViewControllerAnimated; | |
var imp = Marshal.GetFunctionPointerForDelegate (popDelegate); | |
method_setImplementation(method, imp); | |
} | |
[MonoPInvokeCallback(typeof (PopDelegate))] | |
private static IntPtr PopViewControllerAnimated (IntPtr self, IntPtr sel, bool animated) | |
{ | |
// When built for simulator this line returns UINavigationController instance | |
// When build for device with project iOS build setting 'Enable Device Specific Builds' enabled | |
// line also returns UINavigationController. | |
// When build for device with this setting turned off this line returns instance | |
// of __NSMallocBlock__ and subsequent call passing parameters on to original | |
// selector method crashes | |
// This is not specific to the selector chosen for this harness and the marshalling issues | |
// are seen in all cases that have been tried. In our production code we are hooking a number | |
// of selectors on several classes. The solution works for all but the build configuration | |
// outlined above. | |
Console.WriteLine ("PopViewControllerAnimated (self: {0} selector: {1} animated: {2})", new Class (object_getClass (self)).Name, Selector.FromHandle (sel).Name, animated); | |
var navigationController = ObjCRuntime.Runtime.GetNSObject<UINavigationController>(self); | |
Console.WriteLine ("navigationController: {0}", navigationController); | |
var del = (PopDelegate) Marshal.GetDelegateForFunctionPointer (OrigPopImpl,typeof(PopDelegate)); | |
return del (self, sel, animated); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment