Подключение 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, чтобы вы могли пересылать любые сообщения обратно в их объект делегата приложения.
Не требуется никакого алкогольного напитка.