Register the current user for push notifications by using ASP.NET

Overview

This topic shows you how to request push notification registration with Azure Notification Hubs when registration is performed by ASP.NET Web API. This topic extends the tutorial Notify users with Notification Hubs. You must have already completed the required steps in that tutorial to create the authenticated mobile service. For more information on the notify users scenario, see Notify users with Notification Hubs.

Update your app

  1. In your MainStoryboard_iPhone.storyboard, add the following components from the object library:

    • Label: "Push to User with Notification Hubs"

    • Label: "InstallationId"

    • Label: "User"

    • Text Field: "User"

    • Label: "Password"

    • Text Field: "Password"

    • Button: "Login"

      At this point, your storyboard looks like the following:

      Screenshot of the MainStoryboard_iPhone.storyboard app with the components added.

  2. In the assistant editor, create outlets for all the switched controls and call them, connect the text fields with the View Controller (delegate), and create an Action for the login button.

    Screenshot of the assistant editor in the MainStoryboard_iPhone.storyboard app

    Your BreakingNewsViewController.h file should now contain the following code:

    @property (weak, nonatomic) IBOutlet UILabel *installationId;
    @property (weak, nonatomic) IBOutlet UITextField *User;
    @property (weak, nonatomic) IBOutlet UITextField *Password;
    
    - (IBAction)login:(id)sender;
    
  3. Create a class named DeviceInfo, and copy the following code into the interface section of the file DeviceInfo.h:

    @property (readonly, nonatomic) NSString* installationId;
    @property (nonatomic) NSData* deviceToken;
    
  4. Copy the following code in the implementation section of the DeviceInfo.m file:

    @synthesize installationId = _installationId;
    
    - (id)init {
        if (!(self = [super init]))
            return nil;
    
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        _installationId = [defaults stringForKey:@"PushToUserInstallationId"];
        if(!_installationId) {
            CFUUIDRef newUUID = CFUUIDCreate(kCFAllocatorDefault);
            _installationId = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, newUUID);
            CFRelease(newUUID);
    
            //store the install ID so we don't generate a new one next time
            [defaults setObject:_installationId forKey:@"PushToUserInstallationId"];
            [defaults synchronize];
        }
    
        return self;
    }
    
    - (NSString*)getDeviceTokenInHex {
        const unsigned *tokenBytes = [[self deviceToken] bytes];
        NSString *hexToken = [NSString stringWithFormat:@"%08X%08X%08X%08X%08X%08X%08X%08X",
                                ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                                ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                                ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
        return hexToken;
    }
    
  5. In PushToUserAppDelegate.h, add the following property singleton:

    @property (strong, nonatomic) DeviceInfo* deviceInfo;
    
  6. In the didFinishLaunchingWithOptions method in PushToUserAppDelegate.m, add the following code:

    self.deviceInfo = [[DeviceInfo alloc] init];
    
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
    

    The first line initializes the DeviceInfo singleton. The second line starts the registration for push notifications, which is already present if you have already completed the Get Started with Notification Hubs tutorial.

  7. In PushToUserAppDelegate.m, implement the method didRegisterForRemoteNotificationsWithDeviceToken in your AppDelegate and add the following code:

    self.deviceInfo.deviceToken = deviceToken;
    

    This sets the device token for the request.

    Note

    At this point, there should not be any other code in this method. If you already have a call to the registerNativeWithDeviceToken method that was added when you completed the Send push notifications to iOS apps using Azure Notification Hubs tutorial, you must comment-out or remove that call.

  8. In the PushToUserAppDelegate.m file, add the following handler method:

    * (void) application:(UIApplication *) application didReceiveRemoteNotification:(NSDictionary *)userInfo {
       NSLog(@"%@", userInfo);
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notification" message:
                             [userInfo objectForKey:@"inAppMessage"] delegate:nil cancelButtonTitle:
                             @"OK" otherButtonTitles:nil, nil];
       [alert show];
    }
    

    This method displays an alert in the UI when your app receives notifications while it is running.

  9. Open the PushToUserViewController.m file, and return the keyboard in the following implementation:

    - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
        if (theTextField == self.User || theTextField == self.Password) {
            [theTextField resignFirstResponder];
        }
        return YES;
    }
    
  10. In the viewDidLoad method in the PushToUserViewController.m file, initialize the installationId label as follows:

    DeviceInfo* deviceInfo = [(PushToUserAppDelegate*)[[UIApplication sharedApplication]delegate] deviceInfo];
    Self.installationId.text = deviceInfo.installationId;
    
  11. Add the following properties in interface in PushToUserViewController.m:

    @property (readonly) NSOperationQueue* downloadQueue;
    - (NSString*)base64forData:(NSData*)theData;
    
  12. Then, add the following implementation:

    - (NSOperationQueue *)downloadQueue {
        if (!_downloadQueue) {
            _downloadQueue = [[NSOperationQueue alloc] init];
            _downloadQueue.name = @"Download Queue";
            _downloadQueue.maxConcurrentOperationCount = 1;
        }
        return _downloadQueue;
    }
    
    // base64 encoding
    - (NSString*)base64forData:(NSData*)theData
    {
        const uint8_t* input = (const uint8_t*)[theData bytes];
        NSInteger length = [theData length];
    
        static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    
        NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
        uint8_t* output = (uint8_t*)data.mutableBytes;
    
        NSInteger i;
        for (i=0; i < length; i += 3) {
            NSInteger value = 0;
            NSInteger j;
            for (j = i; j < (i + 3); j++) {
                value <<= 8;
    
                if (j < length) {
                    value |= (0xFF & input[j]);
                }
            }
    
            NSInteger theIndex = (i / 3) * 4;
            output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
            output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
            output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
            output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
        }
    
        return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    }
    
  13. Copy the following code into the login handler method created by XCode:

    DeviceInfo* deviceInfo = [(PushToUserAppDelegate*)[[UIApplication sharedApplication]delegate] deviceInfo];
    
    // build JSON
    NSString* json = [NSString stringWithFormat:@"{\"platform\":\"ios\", \"instId\":\"%@\", \"deviceToken\":\"%@\"}", deviceInfo.installationId, [deviceInfo getDeviceTokenInHex]];
    
    // build auth string
    NSString* authString = [NSString stringWithFormat:@"%@:%@", self.User.text, self.Password.text];
    
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://nhnotifyuser.azurewebsites.net/api/register"]];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];
    [request addValue:[@([json lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) description] forHTTPHeaderField:@"Content-Length"];
    [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request addValue:[NSString stringWithFormat:@"Basic %@",[self base64forData:[authString dataUsingEncoding:NSUTF8StringEncoding]]] forHTTPHeaderField:@"Authorization"];
    
    // connect with POST
    [NSURLConnection sendAsynchronousRequest:request queue:[self downloadQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error) {
        // add UIAlert depending on response.
        if (error != nil) {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
            if ([httpResponse statusCode] == 200) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Back-end registration" message:@"Registration successful" delegate:nil cancelButtonTitle: @"OK" otherButtonTitles:nil, nil];
                [alert show];
            } else {
                NSLog(@"status: %ld", (long)[httpResponse statusCode]);
            }
        } else {
            NSLog(@"error: %@", error);
        }
    }];
    

    This method gets both an installation ID and channel for push notifications and sends it, along with the device type, to the authenticated Web API method that creates a registration in Notification Hubs. This Web API was defined in Notify users with Notification Hubs.

Now that the client app has been updated, return to the Notify users with Notification Hubs and update the mobile service to send notifications by using Notification Hubs.