Есть ли способ в obj-c подключиться к методам делегата приложения

Проблема в том, что:

Я использую Marmalade SDK ( https://www.madewithmarmalade.com/).

Marmalade SDK предлагает возможность написания специфичных для платформы плагинов (расширение в их терминологии).

Каждое расширение скомпилировано как статическая библиотека и связано с основным приложением (Loader в их терминологии) с помощью специального инструмента развертывания.

Источники основного приложения не открываются, поэтому у нас нет возможности реализовать / переопределить методы делегата приложения.

Мне нужно расширение для управления удаленными push-уведомлениями через Upsight SDK (ранее PLayhaven).

ios 8 пришел и требует дополнительных усилий для регистрации удаленных push-уведомлений. В частности, должны быть реализованы didRegisterForRemoteNotificationsWithDeviceToken и didRegisterUserNotificationSettings.

Вопросы:

Как я могу внедрить в методы делегата приложения из статической библиотеки (не имея доступа к источникам основного приложения)?

Мысли были:

1) Использование категорий. Я попытался добавить новые методы в класс UIApplication, а затем обменял их на оригинальные. Мои новые методы сделали свое дело, а затем вызвали оригинальные методы. Но, похоже, не работает. Мой опыт работы с объектами довольно плохой. Либо мое расширение класса было неправильно реализовано, либо исходная идея была неправильной:

   @interface UIApplication(MyDelegate)
    - (void)application:(UIApplication *)application newDidRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
    @end

    @implementation UIApplication(MyDelegate)
    - (void)application:(UIApplication *)application newDidRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
    {
        NSLog(@"PLAYHAVEN: didRegisterUserNotificationSettings:%@", notificationSettings);
        [[PHPushProvider sharedInstance] registerUserNotificationSettings:notificationSettings];
    }
    @end

    s3eResult s3ePlayhavenInit_platform()
    {

        // Add any platform-specific initialisation code here
        myDelegate = [[MyDeleagte alloc] init];

        oldHandler1 = class_getInstanceMethod([UIApplication class], @selector(application:didRegisterUserNotificationSettings:));
        newHandler1 = class_getInstanceMethod([UIApplication class], @selector(application:newDidRegisterUserNotificationSettings:));
        method_exchangeImplementations(oldHandler1, newHandler1);

        ...
        return S3E_RESULT_SUCCESS;
    }

2) С помощью NSNotificationCenter прослушайте соответствующие уведомления:

[[NSNotificationCenter defaultCenter] addObserver:myDelegate selector:@selector(didRegisterUserNotificationSettings:) name:@"UIApplicationDidRegisterUserNotificationSettings" object:nil];

Но я не уверен, что уведомление с таким именем будет вообще размещено. Мне не удалось найти какие-либо соответствующие константы в классе UIApplication. В результате это также не работает.

Последний вопрос:

Это вообще возможно? Есть идеи?

Спасибо всем.

1 ответ

Этот метод (1) будет работать отдельно от функции didRegisterUserNotificationSettings, являющейся частью UIApplicationDelegate. Хитрость для получения правильного делегата состоит в том, чтобы перехватить функцию setDelegate UIApplication, а затем выполнить метод, перебивающий класс делегата.

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