Подключение Objective C к [AppDelegate openUrl]

Среда

  • xcode 6.4
  • Objective-C
  • iOS-приложение

Использование регистра

  • Продукт представляет собой SDK, интегрированный в сторонние приложения
  • Нет доступа к исходному коду приложения с помощью SDK
  • Модули в SDK должны получить URL-адрес, используемый для запуска приложения (если есть)

Проблема под рукой

Имея в виду вышеупомянутый вариант использования, как я могу получить URL-адрес, использованный для запуска приложения (если есть), ИЛИ для перехвата метода openUrl, реализованного в AppDelegate для приложений?

2 ответа

Это на самом деле довольно просто, с SDK, связанным как DyLib, и основным объектом, инициализированным в разделе "attribute((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);

    ...
}

Вы можете создать свой собственный класс, который реализует UIApplicationDelegate протокол. В стартовом коде вашего SDK (который пользователь должен будет вызвать раньше application:willFinishLaunchingWithOptions:), создайте его экземпляр и замените основной объект UIApplication delegate с вашим пользовательским объектом.

Ваш пользовательский объект теперь является делегатом приложения, а не их.

Перед настройкой делегата объекта UIApplication установите делегат вашего класса на текущий делегат UIApplication, чтобы вы могли пересылать любые сообщения обратно в их объект делегата приложения.

Не требуется никакого алкогольного напитка.

Другие вопросы по тегам