0

The problem is:

I use Marmalade SDK (http://www.madewithmarmalade.com/).

Marmalade SDK offers opportunity to write platform-specific plugins (extension in their terminology).

Every extension is compiled as static-library and linked to the main application (Loader in their terminology) with special deploy tool.

Sources of the main application are not opened, thus we have no ability to implement/override app delegate methods.

I need an extension for managing remote push notifications via Upsight SDK (formerly PLayhaven).

ios 8 came and requires some additional efforts for remote push notifications registration. In particular, didRegisterForRemoteNotificationsWithDeviceToken and didRegisterUserNotificationSettings should be implemented.

The questions are:

How can I inject into application delegate methods from static library (having no access to the sources of the main application)?

The thoughts were:

1) Using categories. I tried to add new methods to UIApplication class, then exchanged them with original ones. My new methods did their work and then invoked original methods. But it seems not working. My obj-c experience is pretty poor. Either my class extension was wrong implemented or the original idea was incorrect:

   @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) Using NSNotificationCenter listen to the corresponding notifications:

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

But I'm not sure that the notification with such name will be posted at all. I did not managed to find any relevant constans in UIApplication class. As result, this also doesn't work.

The final question is:

It's possible at all? Any ideas?

Thanks all.

papirosnik
  • 311
  • 1
  • 3
  • 14

1 Answers1

0

This technique (1) would work apart from didRegisterUserNotificationSettings function is a part of UIApplicationDelegate. The trick to get the right delegate is to hook setDelegate function of UIApplication and then do method swizzling on delegate class.

shader
  • 2,121
  • 1
  • 13
  • 20