0

环境

  • 代码 6.4
  • Objective-C
  • iOS 应用程序

用例

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

手头的问题

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

4

2 回答 2

1

您可以创建自己的实现UIApplicationDelegate协议的类。在您的 SDK 的启动代码(用户必须在类似 的早期调用application:willFinishLaunchingWithOptions:)中,实例化它,并用您的自定义对象替换主 UIApplicationdelegate对象。

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

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

无需搅拌。

于 2015-08-11T18:22:20.580 回答
1

这实际上非常简单,将 SDK 链接为 DyLib 并在“属性((构造函数))”部分中初始化主对象,需要以下内容:

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);

    ...
}
于 2015-08-11T19:05:18.337 回答