通过使用 ASP.NET 注册推送通知的当前用户Register the current user for push notifications by using ASP.NET

概述Overview

本主题演示在 ASP.NET Web API 执行注册时如何请求向 Azure 通知中心注册推送通知。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. 在 MainStoryboard_iPhone.storyboard 中,从对象库添加以下组件:In your MainStoryboard_iPhone.storyboard, add the following components from the object library:

    • 标签:“Push to User with Notification Hubs”Label: "Push to User with Notification Hubs"

    • 标签:“InstallationId”Label: "InstallationId"

    • 标签:“User”Label: "User"

    • 文本字段:“User”Text Field: "User"

    • 标签:“Password”Label: "Password"

    • 文本字段:“Password”Text Field: "Password"

    • 按钮:“Login”Button: "Login"

      此时,Storyboard 应与下图类似:At this point, your storyboard looks like the following:

  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.

    BreakingNewsViewController.h 文件现在应当包含以下代码: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. 创建一个名为 DeviceInfo 的类,将以下代码复制到 DeviceInfo.h 文件的 interface 部分: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. 在文件 DeviceInfo.m 的实现部分中复制以下代码: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. 在 PushToUserAppDelegate.h 中,添加以下单一属性:In PushToUserAppDelegate.h, add the following property singleton:

    @property (strong, nonatomic) DeviceInfo* deviceInfo;
    
  6. 在 PushToUserAppDelegate.m 中的 didFinishLaunchingWithOptions 方法中,添加以下代码:In the didFinishLaunchingWithOptions method in PushToUserAppDelegate.m, add the following code:

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

    第一行初始化 DeviceInfo 单一实例。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. 在 PushToUserAppDelegate.m 中,在 AppDelegate 中实现 didRegisterForRemoteNotificationsWithDeviceToken 方法并添加以下代码: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.

    备注

    此时,此方法中不应有任何其他代码。At this point, there should not be any other code in this method. 如果已调用在完成通知中心入门教程的学习时添加的 registerNativeWithDeviceToken 方法,必须注释掉或删除该调用。If you already have a call to the registerNativeWithDeviceToken method that was added when you completed the Get Started with Notification Hubs tutorial, you must comment-out or remove that call.

  8. PushToUserAppDelegate.m 文件中,添加以下处理程序方法: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];
    }
    

    当你的应用程序接收到它正在运行的通知时,此方法会在 UI 中显示一个警报。This method displays an alert in the UI when your app receives notifications while it is running.

  9. 打开 PushToUserViewController.m 文件,并在以下实现中返回键盘: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. PushToUserViewController.m 文件中的 viewDidLoad 方法中,如下所示初始化 installationId 标签: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. PushToUserViewController.m 中的 interface 部分中添加以下属性: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. 将以下代码复制到由 XCode 创建的 login 处理程序方法: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.chinacloudsites.cn/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);
        }
    }];
    

    此方法获取一个安装 ID 和用于推送通知的通道并将它与设备类型一起发送到在通知中心创建注册的已经身份验证的 Web API 方法。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. 此 Web API 已在 使用通知中心通知用户中定义。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.