I've followed these Notification Hub resources and have not been successful in receiving push notifications on my iOS device.
I've checked, rechecked, and rechecked my setup:
A demo application that is generating push notifications:
while (true)
{
string connectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSecretWithFullAccess("myhubname-ns", "…snip");
var hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, "myhubname");
var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
iosPayload.CustomFields.Add("inAppNotification", "Hello!");
hubClient.SendAppleNativeNotification(iosPayload.ToJsonString());
Console.WriteLine("Sent");
Thread.Sleep(20000);
}
No exceptions or issues are generated. Mangling any of the namespace, keys or hub names causes exceptions to be thrown, and fiddler response code from Azure is 2xx so all looks well.
I see registration occur correctly per code below:
:
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) deviceToken {
NSString* connectionString = [SBConnectionString stringWithEndpoint:@"https://gift-ns.servicebus.windows.net/" listenAccessSecret:@"…snip"];
self.hub = [[SBNotificationHub alloc] initWithConnectionString:connectionString notificationHubPath:@"gift-usw-dev"];
[self.hub refreshRegistrationsWithDeviceToken:deviceToken completion:^(NSError* error) {
if (error == nil) {
[self.hub defaultRegistrationExistsWithCompletion:^(BOOL exists, NSError* error2) {
if (error2 == nil) {
if (!exists) {
[self.hub createDefaultRegistrationWithTags:nil completion:^(NSError* error3) {
if (error3 != nil) {
NSLog(@"Error creating default registration: %@", error3);
}
}];
}
} else {
NSLog(@"Error retrieving default registration: %@", error2);
}
}];
} else {
NSLog(@"Error refreshing device token: %@", error);
}
}];
}
After starting the demo app, then running the iOS application, here is the resultant dashboard which I have no idea how to read effectively.
Thinking that my certificates were not correct, or something was lost between Azure and APS, I dug into troubleshooting the APS service and found this: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html and jumped to the section Problems Connecting to the Push Service
And ran this command:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert YourSSLCertAndPrivateKey.pem -debug -showcerts -CAfile server-ca-cert.pem
But I didn't have a .pem file (OSX), so I found this command to get them:
openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes
where keyStore.pfx was the renamed version of the .p12 exported from the Keychain for the push notification cert.
The command ran fine. What is happening?
The AppleNotificationJsonBuilder does not serialize the payload correctly using the latest nuget of Service Bus preview features.
So, per the examples from msdn instructions:
var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
iosPayload.CustomFields.Add("inAppNotification", "Hello!");
Console.Log(iosPayload.ToJsonString());
Generates:
{"aps":{"alert":"This is a test"},"inAppNotification":Hello! This is a test}
Which is malformed. Well formed is "string"
{"aps":{"alert":"This is a test"},"inAppNotification":"Hello! This is a test"}
Custom payloads are fine per http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
One solution is to use Json.NET, or ping someone internally at Microsoft.
Open issues:
Hopefully this saves someone their afternoon.