繁体   English   中英

Objective-C挂钩到[AppDelegate openUrl]

[英]Objective-C hooking to [AppDelegate openUrl]

环境

  • xcode 6.4
  • 目标C
  • iOS应用

用例

  • 该产品是集成在第三方应用程序中的SDK
  • 使用SDK无法访问应用程序的源代码
  • SDK中的模块应检索用于启动应用程序的URL(如果有)

眼前的问题

考虑到上述用例,我如何检索用于启动应用程序的URL(如果有的话),或者,以拦截由Applications AppDelegate实现的'openUrl'方法?

您可以创建自己的实现UIApplicationDelegate协议的类。 在SDK的启动代码(用户将必须在早期的application:willFinishLaunchingWithOptions:类的调用中)中进行实例化,然后将主UIApplication对象的delegate替换为您的自定义对象。

您的自定义对象现在是应用程序委托,而不是他们的委托。

在设置UIApplication对象的委托之前,请将您的类的委托设置为当前的UIApplication委托,以便您可以将任何消息转发回其应用程序委托对象。

无需打毛。

这实际上非常简单,将SDK链接为DyLib,并将主对象初始化在“ 属性 ((constructor))”部分中,这是需要的:

IMP g_originalSetDelegate           = nil;
IMP g_originalOpenUrl               = nil;

BOOL swizzle_openUrl(id self, SEL _cmd, UIApplication* application, NSURL* url, NSString* sourceApplication, id annotation) {
    // TBD: Do your magic
    return ((BOOL(*)(id,SEL,UIApplication*,NSURL*,NSString*,id))g_originalOpenUrl)(self, _cmd, application, url, sourceApplication, annotation);
}

void swizzle_setDelegate(id self, SEL _cmd, id delegate) {
    ((void(*)(id,SEL,id))g_originalSetDelegate)(self, _cmd, delegate);// Call the original method

    auto method  = class_getInstanceMethod([delegate class], @selector(application:openURL:sourceApplication:annotation:));
    g_originalOpenUrl  = method_getImplementation(method);
    method_setImplementation(method, (IMP)swizzle_openUrl);
}

-(id)init {
    auto method  = class_getInstanceMethod([UIApplication class], @selector(setDelegate:));
    g_originalSetDelegate = method_getImplementation(method);
    method_setImplementation(method, (IMP)swizzle_setDelegate);

    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM