By Adam Nagy
As I understand, if you want to receive notifications inside an iOS application even when it goes into the background or gets terminated, then the only way is via Apple Push Notification (APN). If you only need those notifications while your program is running then there seem to be other webservices that provide such functionality and enable you to get notified about certain events without having to keep polling the service.
Here is a good overview of this process on the Apple Developer site:
Apple Push Notification Service
In order to get started with APN and test this functionality you need three things:
- Enable your device for APN though the Apple Developer portal
- Register your application for APN when it starts up
- Send an APN message to your device
Enable your device for APN though the Apple Developer portal
There are quite a few articles that take you through the necessary steps. I found the following ones useful:
http://www.ibm.com/developerworks/java/library/mo-ios-push/
http://42spikes.com/post/Sending-Apple-Push-Notifications-from-a-C-Application.aspx
When you are registering a new App ID on the iOS Povisioning Portal then you cannot use a wildcard character (*) in its name if you want to enable APN for it.
Because previously in all my applications I was using an App ID with a wildcard character in it, I did not realize that Xcode automatically adds the Bundle Seed ID to the project - i.e. I did not read this section on the iOS Provisioning Portal properly:
"The Bundle Seed ID portion of your App ID does not need to be input into Xcode."
Not only does it not need to be input in Xcode, it should not be input there, because in that case after Xcode automatically adds the Bundle Seed ID to your project's Bundle Identifier it will not match the exact App ID string that your provisioning profile is for and so you won't be able to compile your application with that provisioning profile.
Register your application for APN when it starts up
The Apple Developer site provides a good overview of the steps needed to achieve this:
Registering for remote notifications
When you get the message that you successfully registered for APN in your program, then you'll get the token that others need to use in order to send you an APN. This token only changes if the user restores backup data to a new device or reinstalls the operating system.
You'll get this device token inside didRegisterForRemoteNotificationsWithDeviceToken, from where you could send it on to the application that wants to be able to send you notifications. For testing purposes you could simply get this token as a string when debugging your app on your iPad, and then copy/paste this string somewhere, so you could reuse it in the application that will send your iPad notifications:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken
{
NSString * str = [devToken description];
// now copy/paste its value somewhere for later use
}
The first time your application will try to register for APN there will be a message popping up on the iPad where you'll have to enable this functionality by hand.
Note: since the token is device specific, therefore the APN registration will fail when testing your iOS application on the simulator.
Send an APN message to your device
Now I want to send a message to my iPad from my .NET application. I've found a nice project which makes creating these notifications quite easy: APNS-Sharp
This also has a .NET test project that I could use straight away. I just had to modify the testDeviceToken, p12File and p12FilePassword string variables in the program and it was ready to go. For testDeviceToken I used the string that I previously saved to a text file. Note that you need to remove all spaces from it so that you'll end up with a 64 characters long string containing only letters and numbers.
If you followed the above mentioned articles that take you through the process of enabling your device for accepting APN's, then there you've seen that you'll need to download the Development Push SSL Certificate. Once you install that on your Mac, then you'll be able to export it from Keychain Access as a p12 file with a password of your choice. This is the password that p12FilePassword needs to be set to.
I also changed the test project to only send a single notification. When you run the program, then in the console it provides information about the notification data that has been sent. If all goes well, then your iOS application will get the notification like so:
Depending on whether your application is running (inc. in background) or not, a different function of your iOS app will be called. If you get a notification while your application is running, the didReceiveRemoteNotification function will be called, and that's where you can get the message text from:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString * message = nil;
NSDictionary * apsDict = [userInfo objectForKey:@"aps"];
id alert = [apsDict objectForKey:@"alert"];
if ([alert isKindOfClass:[NSString class]]) {
message = alert;
} else if ([alert isKindOfClass:[NSDictionary class]]) {
message = [alert objectForKey:@"body"];
}
}
Otherwise you'll have to do it from didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
NSDictionary * userInfo = [launchOptions
objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSString * message = nil;
NSDictionary * apsDict = [userInfo objectForKey:@"aps"];
id alert = [apsDict objectForKey:@"alert"];
if ([alert isKindOfClass:[NSString class]]) {
message = alert;
} else if ([alert isKindOfClass:[NSDictionary class]]) {
message = [alert objectForKey:@"body"];
}
// You may want to clear the notification badge
application.applicationIconBadgeNumber = 0;
return YES;
}
One thing to note is that if a notification arrives when your application is not running in the foreground and the user either ignores the notification banner (when the Alert Style setting of the application is set to Banners) or clicks Close in the notification dialog instead of Launch (when the Alert Style of the application is set to Alerts) then the application will not know about the notification and will not be able to get its message text either.
Comments