5

I am updating my iOS application to work with iOS8 but running into problems getting the device token for remote notifications.

I have updated my AppDelegate to call RegisterUserNotificationSettings to register when using iOS8, leaving previous versions to call RegisterForRemoteNotificationTypes:

var version8 = new Version (8,0);

        if (new Version(UIDevice.CurrentDevice.SystemVersion) < version8) 
        {
            var notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes (notificationTypes);
        }
        else
        {
            var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());
            UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
        }

I also have the following methods in my AppDelegate class:

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        NSString str = (NSString)Runtime.GetNSObject(Messaging.intptr_objc_msgSend(deviceToken.Handle, new Selector("description").Handle));
        _deviceTokenString = str.ToString().Replace("<", "").Replace(">", "").Replace(" ", "");
        Trace.trace("Device Token: " + _deviceTokenString);
}

and

public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings)
    {
        // Get Device Token
    }

However I don't know how to get the device token in DidRegisterUserNotificationSettings

I have read that in objective-c there is: didRegisterForRemoteNotificationsWithDeviceToken but this doesn't seem to be available in Xamarin (or at least I don't know how to call it).

binncheol
  • 1,393
  • 4
  • 22
  • 38

2 Answers2

5

Simple answer, I was missing the following line of code when registering:

UIApplication.SharedApplication.RegisterForRemoteNotifications();

Adding this line meant that the code entered the RegisteredForRemoteNotifications handler.

So the complete code for registering for notifications is:

var version8 = new Version (8,0);
        if (new Version(UIDevice.CurrentDevice.SystemVersion) < version8) 
        {
            var notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes (notificationTypes);
        }
        else
        {
            var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());
            UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
            UIApplication.SharedApplication.RegisterForRemoteNotifications();
        }
binncheol
  • 1,393
  • 4
  • 22
  • 38
  • 1
    It would appear that Objective-C folks prefer calling `RegisterForRemotNotifications` inside `DidRegisterUserNotificationSettings` (see http://stackoverflow.com/a/24488651/1644813). I am not sure what threading model is used behind the scenes, but in the event that `RegisterForRemotNotifications` does not complete synchronously using `DidRegisterUserNotificationSettings` would be a safer bet. – Kirill Shlenskiy Sep 17 '14 at 08:14
0

There's not enough code to be sure what's wrong. I suspect you're changed what you're calling (not just added new calls, like described here). If that does not help (or is not clear) then you might want to update your question with more of the code you're using.

Also you should be able to replace this:

NSString str = (NSString)Runtime.GetNSObject(Messaging.intptr_objc_msgSend(deviceToken.Handle, new Selector("description").Handle));
_deviceTokenString = str.ToString().Replace("<", "").Replace(">", "").Replace(" ", "");

with:

_deviceTokenString = deviceToken.Description.Replace("<", "").Replace(">", "").Replace(" ", "");

Finally:

I have read that in objective-c there is: didRegisterForRemoteNotificationsWithDeviceToken but this doesn't seem to be available in Xamarin.

You likely mean application:didRegisterForRemoteNotificationsWithDeviceToken: which, in Xamarin.iOS, maps to UIApplicationDelegate.RegisteredForRemoteNotifications, which you said is not called anymore (on iOS8).

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174
  • I've updated my question with some code to hopefully make what I'm doing more understandable. I haven't removed any of the old code - just added in the call to RegisterUserNotificationSettings when iOS8 and adding the DidRegisterUserNotificationSettings handler. – binncheol Sep 17 '14 at 07:20