Search code examples
iosapple-push-notificationsdevicetoken

application:didRegisterForRemoteNotificationsWithDeviceToken: Not Firing When Using Developer Provisioning Profile


In Ad Hoc builds I see the application:didRegisterForRemoteNotificationsWithDeviceToken: event called but not when I use a DEBUG build using a developer provisioning profile. The Ad Hoc and Developer Provisioning Profile are using the same App ID.

App ID Screenshot: enter image description here

When running using the developer provisioning profile I did see the alert asking about whether or not to enable push notifications. I chose to use push notifications, but then the event application:didRegisterForRemoteNotificationsWithDeviceToken: never occurred. Note that the event for application:didFailToRegisterForRemoteNotificationsWithError: also does not occur.

Note that in application:didFinishLaunchingWithOptions: I have:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
   // Other code...
}

I'm pretty puzzled by this one.

Other Notes:

  • My iPad 2 and iPod 4 I am using are NOT jail broken
  • I was seeing the dreaded no valid 'aps-environment' entitlement string found for application error, but this resolved after regenerating my development provisioning profile.
  • A co-worker of mine has seen this same issue (works on Ad Hoc but not developer) on projects with previous companies.

Solution

  • Same Code Worked Next Day

    The event application:didRegisterForRemoteNotificationsWithDeviceToken:deviceToken is working now (the next day). Note that this seems to have had nothing to do with the alert asking whether you want to enable push notifications as I didn't see this alert when it began working.

    One thing I still find odd is that yesterday using Ad Hoc build the event application:didRegisterForRemoteNotificationsWithDeviceToken:deviceToken fired EVERY TIME I launched the app. However, a DEBUG build with a developer provisioning profile never fired at all. Same code this morning works (and fires every time using a DEBUG build with a developer provisioning profile).... Something in the device (internal timer / timeout) must have reset.

    Sample Code

    Below is the code I used in the event receiving the deviceToken. It uses Urban Airship as the provider to the Apple Push Notification Server (APNS). I've removed the username and passwords from the code. I hope this is useful to others who are trying to figure things out.

    - (void)application:(UIApplication *)application
            didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        NSString *tokenStr = [[[[deviceToken description]
                                stringByReplacingOccurrencesOfString:@"<" withString:@""]
                               stringByReplacingOccurrencesOfString:@">" withString:@""]
                              stringByReplacingOccurrencesOfString:@" " withString:@""];
    
        NSLog(@"Device Token (raw): %@", deviceToken);
        NSLog(@"Device Token (string): %@", tokenStr);
        UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Device Token"
                                                     message:tokenStr
                                                    delegate:nil
                                           cancelButtonTitle:nil
                                           otherButtonTitles:@"OK", nil] autorelease];
        [alert show];
    
        // Code to send token to server
        NSString *urlString = [NSString stringWithFormat:
        @"https://go.urbanairship.com/api/device_tokens/%@", tokenStr];
        ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:
                                   [NSURL URLWithString:urlString]];
    #if APP_STORE_RELEASE
        [request addBasicAuthenticationHeaderWithUsername:@"aaaaaaaaaaaaaaaaaaaaaa"
                                              andPassword:@"bbbbbbbbbbbbbbbbbbbbbb"];
    #else
        [request addBasicAuthenticationHeaderWithUsername:@"cccccccccccccccccccccc"
                                              andPassword:@"dddddddddddddddddddddd"];
    #endif
        request.requestMethod = @"PUT";
        [request startAsynchronous];
    }
    

    Note that the description of the NSData will return a Hex string that begins with a "<" and ends with a ">". In between are spaces. My original approach was to convert the NSData into a string using NSUTF8StringEncoding but this is wrong (since you want the token as a hexadecimal string).