概觀
本教學課程示範如何使用 Azure 通知中樞,將突發新聞通知廣播至 iOS 應用程式。 完成後,您可以註冊您感興趣的突發新聞類別,並且僅收到這些類別的推送通知。 此案例是許多應用程式的常見模式,其中通知必須傳送給先前已宣告有興趣的使用者群組,例如 RSS 閱讀器、音樂迷的應用程式等。
在通知中樞內建立註冊時,您可以透過包含一或多個 tags 來啟用廣播案例。 當通知傳送至標籤時,已註冊標籤的裝置會收到通知。 因為標籤只是字串,所以不需要事先佈建。 如需標籤的詳細資訊,請參閱 通知中樞路由和標籤運算式。
在本教學課程中,您將採取下列步驟:
- 將類別選擇新增至應用程式
- 傳送標記通知
- 從裝置傳送通知
- 運行應用程序並生成通知
先決條件
本主題以您在 教學課程:使用 Azure 通知中樞將通知推送至 iOS 應用程式中建立的應用程式為基礎。 在開始本教學課程之前,您必須先完成 教學課程:使用 Azure 通知中樞將通知推送至 iOS 應用程式。
將類別選擇添加到應用程序
第一個步驟是將 UI 元素新增至現有的分鏡腳本,讓使用者能夠選取要註冊的類別。 使用者選取的類別會儲存在裝置上。 當應用程式啟動時,會在通知中樞建立裝置註冊,並將選取的類別作為標籤。
在 MainStoryboard_iPhone.storyboard 中,從物件庫新增下列元件:
帶有 突發新聞文本的標籤。
帶有類別文本世界、政治、商業、技術、科學和體育的標籤。
預設情況下,六個交換機(每個類別一個)將每個交換機 狀態 設置為 關閉 。
一個標有 「訂閱」的按鈕。
您的分鏡腳本應如下所示:
在輔助編輯器中,為所有交換機創建插座,並將它們命名為 WorldSwitch、 PoliticsSwitch、 BusinessSwitch、 TechnologySwitch、 ScienceSwitch 和 SportsSwitch。
請為您的按鈕建立一個名為
subscribe的動作;其中ViewController.h應包含以下程式碼:@property (weak, nonatomic) IBOutlet UISwitch *WorldSwitch; @property (weak, nonatomic) IBOutlet UISwitch *PoliticsSwitch; @property (weak, nonatomic) IBOutlet UISwitch *BusinessSwitch; @property (weak, nonatomic) IBOutlet UISwitch *TechnologySwitch; @property (weak, nonatomic) IBOutlet UISwitch *ScienceSwitch; @property (weak, nonatomic) IBOutlet UISwitch *SportsSwitch; - (IBAction)subscribe:(id)sender;建立名為 的新 Cocoa Touch 類別
Notifications。 複製 Notifications.h 檔案的介面區段中的下列程式碼:@property NSData* deviceToken; - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName; - (void)storeCategoriesAndSubscribeWithCategories:(NSArray*)categories completion:(void (^)(NSError* error))completion; - (NSSet*)retrieveCategories; - (void)subscribeWithCategories:(NSSet*)categories completion:(void (^)(NSError *))completion;將下列匯入指示詞新增至 Notifications.m:
#import <WindowsAzureMessaging/WindowsAzureMessaging.h>複製檔案 Notifications.m 的實作區段中的下列程式碼。
SBNotificationHub* hub; - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName{ hub = [[SBNotificationHub alloc] initWithConnectionString:listenConnectionString notificationHubPath:hubName]; return self; } - (void)storeCategoriesAndSubscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; [defaults setValue:[categories allObjects] forKey:@"BreakingNewsCategories"]; [self subscribeWithCategories:categories completion:completion]; } - (NSSet*)retrieveCategories { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSArray* categories = [defaults stringArrayForKey:@"BreakingNewsCategories"]; if (!categories) return [[NSSet alloc] init]; return [[NSSet alloc] initWithArray:categories]; } - (void)subscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion { NSString* templateBodyAPNS = @"{\"aps\":{\"alert\":\"$(messageParam)\"}}"; [hub registerTemplateWithDeviceToken:self.deviceToken name:@"simpleAPNSTemplate" jsonBodyTemplate:templateBodyAPNS expiryTemplate:@"0" tags:categories completion:completion]; }這個類別會使用本機儲存體來儲存和擷取此裝置接收的新聞類別。 此外,它還包含使用 範本 來註冊這些類別的方法。
在
AppDelegate.h檔案中,新增Notifications.h的 import 陳述式,並為Notifications類別的實例新增屬性:#import "Notifications.h" @property (nonatomic) Notifications* notifications;在
didFinishLaunchingWithOptions中的AppDelegate.m方法中,請在方法開頭新增程式碼以初始化通知實例。
HUBNAME與HUBLISTENACCESS(定義於hubinfo.h中) 的<hub name>和<connection string with listen access>預留位置,應已用稍早取得的 DefaultListenSharedAccessSignature 的通知中樞名稱與連接字串所取代self.notifications = [[Notifications alloc] initWithConnectionString:HUBLISTENACCESS HubName:HUBNAME];備註
由於與用戶端應用程式一同散發的認證通常不安全,因此您應該只與用戶端應用程式散發用於收聽權限的金鑰。 接聽存取權可讓您的應用程式註冊通知,但無法修改現有的註冊,也無法傳送通知。 完整存取金鑰用於安全後端服務中,用於傳送通知和變更現有註冊。
在
didRegisterForRemoteNotificationsWithDeviceToken中的AppDelegate.m方法裡,將此方法中的程式碼取代為下列程式碼,以便將設備權杖傳遞給notifications類別。notifications類別會為通知執行與類別之間的註冊。 如果使用者變更類別選取項目,請呼叫subscribeWithCategories方法以回應 訂閱 按鈕以更新它們。備註
由於 Apple Push Notification Service (APNS) 指派的裝置權杖隨時可能改變,因此您應經常註冊通知以避免通知失敗。 此範例會在每次應用程式啟動時註冊通知。 對於經常執行的應用程式 (每天超過一次),如果距離上次註冊不到一天,您可以略過註冊以保留頻寬。
self.notifications.deviceToken = deviceToken; // Retrieves the categories from local storage and requests a registration for these categories // each time the app starts and performs a registration. NSSet* categories = [self.notifications retrieveCategories]; [self.notifications subscribeWithCategories:categories completion:^(NSError* error) { if (error != nil) { NSLog(@"Error registering for notifications: %@", error); } }];此時,方法中
didRegisterForRemoteNotificationsWithDeviceToken應該沒有其他程式碼。在完成
AppDelegate.m教學課程時,以下方法應已出現在中。 如果沒有,請添加它們。- (void)MessageBox:(NSString *)title message:(NSString *)messageText { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:messageText delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo { NSLog(@"%@", userInfo); [self MessageBox:@"Notification" message:[[userInfo objectForKey:@"aps"] valueForKey:@"alert"]]; }這個方法會透過顯示簡單的 UIAlert 來處理應用程式執行時收到的通知。
在
ViewController.m中,新增import陳述式AppDelegate.h,並將下列程式碼複製到 Xcode 所生成的subscribe方法中。 此程式碼會更新通知註冊,以使用使用者在使用者介面中選擇的新類別標籤。#import "Notifications.h" NSMutableArray* categories = [[NSMutableArray alloc] init]; if (self.WorldSwitch.isOn) [categories addObject:@"World"]; if (self.PoliticsSwitch.isOn) [categories addObject:@"Politics"]; if (self.BusinessSwitch.isOn) [categories addObject:@"Business"]; if (self.TechnologySwitch.isOn) [categories addObject:@"Technology"]; if (self.ScienceSwitch.isOn) [categories addObject:@"Science"]; if (self.SportsSwitch.isOn) [categories addObject:@"Sports"]; Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications]; [notifications storeCategoriesAndSubscribeWithCategories:categories completion: ^(NSError* error) { if (!error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:"Notification" message:"Subscribed" delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } else { NSLog(@"Error subscribing: %@", error); } }];這個方法會建立類別
NSMutableArray,並使用類別將Notifications清單儲存在本機儲存體中,並將對應的標籤註冊到通知中樞。 變更類別時,會使用新類別重新建立註冊。在
ViewController.m方法中viewDidLoad新增以下程式碼,以根據先前儲存的類別來設定使用者介面。// This updates the UI on startup based on the status of previously saved categories. Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications]; NSSet* categories = [notifications retrieveCategories]; if ([categories containsObject:@"World"]) self.WorldSwitch.on = true; if ([categories containsObject:@"Politics"]) self.PoliticsSwitch.on = true; if ([categories containsObject:@"Business"]) self.BusinessSwitch.on = true; if ([categories containsObject:@"Technology"]) self.TechnologySwitch.on = true; if ([categories containsObject:@"Science"]) self.ScienceSwitch.on = true; if ([categories containsObject:@"Sports"]) self.SportsSwitch.on = true;
應用程式現在可以在應用程式啟動時,將一組類別儲存在裝置本機儲存中,用來向通知中樞註冊。 使用者可以在執行階段變更類別的選取,並按一下 subscribe 方法來更新裝置的註冊。 接下來,您更新應用程序以直接在應用程序本身中發送突發新聞通知。
(選用)傳送標記通知
如果您無法存取 Visual Studio,您可以跳至下一節,並從應用程式本身傳送通知。 您也可以使用通知中心的偵錯索引標籤,從 Azure 入口網站 傳送適當的範本通知。
在本節中,您會從 .NET 主控台應用程式傳送突發新聞作為標記範本通知。
在 Visual Studio 中,建立新的 Visual C# 主控台應用程式:
- 在功能表上,選取 [ 檔案>新增>專案]。
- 在 [ 建立新專案] 中,選取範本清單中的 [適用於 C# 的 主控台應用程式 (.NET Framework)] ,然後選取 [ 下一步]。
- 輸入應用程式的名稱。
- 針對 [解決方案],選擇 [ 新增至解決方案],然後選取 [建立 ] 以建立專案。
選取 [工具]> [NuGet 套件管理員>] [套件管理員] [主控台],然後在主控台視窗中執行下列命令:
Install-Package Microsoft.Azure.NotificationHubs此動作會使用 Microsoft.Azure.NotificationHubs 套件來新增對 Azure 通知中樞 SDK 的參考。
開啟 Program.cs 檔案,然後新增下列
using陳述式:using Microsoft.Azure.NotificationHubs;在類別中
Program,新增下列方法,或取代它,如果它已經存在:private static async void SendTemplateNotificationAsync() { // Define the notification hub. NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>"); // Apple requires the apns-push-type header for all requests var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}}; // Create an array of breaking news categories. var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"}; // Send the notification as a template notification. All template registrations that contain // "messageParam" and the proper tags will receive the notifications. // This includes APNS, GCM/FCM, WNS, and MPNS template registrations. Dictionary<string, string> templateParams = new Dictionary<string, string>(); foreach (var category in categories) { templateParams["messageParam"] = "Breaking " + category + " News!"; await hub.SendTemplateNotificationAsync(templateParams, category); } }此程式碼會針對字串陣列中的六個標籤中的每一個傳送範本通知。 標籤的使用可確保裝置僅收到已註冊類別的通知。
在上述程式碼中,請使用您的通知中樞名稱及通知中樞儀表板的
<hub name>連接字串,來取代<connection string with full access>和 預留位置。在方法中
Main(),新增下列行:SendTemplateNotificationAsync(); Console.ReadLine();建置主控台應用程式。
(選用)從裝置傳送通知
通常通知會由後端服務發送,但您可以直接從應用程序發送突發新聞通知。 若要這樣做,請更新 SendNotificationRESTAPI 您在 通知中樞入門 教學課程中定義的方法。
在
ViewController.m中,請更新SendNotificationRESTAPI方法,如下所示,使其接受類別標籤的參數,並傳送適當的 範本 通知。- (void)SendNotificationRESTAPI:(NSString*)categoryTag { NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:nil]; NSString *json; // Construct the messages REST endpoint NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/messages/%@", HubEndpoint, HUBNAME, API_VERSION]]; // Generated the token to be used in the authorization header. NSString* authorizationToken = [self generateSasToken:[url absoluteString]]; //Create the request to add the template notification message to the hub NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; // Add the category as a tag [request setValue:categoryTag forHTTPHeaderField:@"ServiceBusNotification-Tags"]; // Template notification json = [NSString stringWithFormat:@"{\"messageParam\":\"Breaking %@ News : %@\"}", categoryTag, self.notificationMessage.text]; // Signify template notification format [request setValue:@"template" forHTTPHeaderField:@"ServiceBusNotification-Format"]; // JSON Content-Type [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"]; //Authenticate the notification message POST request with the SaS token [request setValue:authorizationToken forHTTPHeaderField:@"Authorization"]; //Add the notification message body [request setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]]; // Send the REST request NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response; if (error || httpResponse.statusCode != 200) { NSLog(@"\nError status: %d\nError: %@", httpResponse.statusCode, error); } if (data != NULL) { //xmlParser = [[NSXMLParser alloc] initWithData:data]; //[xmlParser setDelegate:self]; //[xmlParser parse]; } }]; [dataTask resume]; }在
ViewController.m中,更新Send Notification動作,如下列程式碼所示。 這樣它就使用每個標籤單獨發送通知並發送到多個平台。- (IBAction)SendNotificationMessage:(id)sender { self.sendResults.text = @""; NSArray* categories = [NSArray arrayWithObjects: @"World", @"Politics", @"Business", @"Technology", @"Science", @"Sports", nil]; // Lets send the message as breaking news for each category to WNS, FCM, and APNS // using a template. for(NSString* category in categories) { [self SendNotificationRESTAPI:category]; } }重建您的專案,並確定您沒有建置錯誤。
運行應用程序並生成通知
按 [執行] 按鈕來建置專案並啟動應用程式。 選擇一些要訂閱的突發新聞選項,然後 按訂閱按鈕 。 您應該會看到一個對話框,指出通知已訂閱。
當您選擇 [ 訂閱] 時,應用程式會將選取的類別轉換成標籤,並從通知中樞要求所選標籤的新裝置註冊。
輸入要作為突發新聞發送的訊息,然後按 發送通知 按鈕。 或者,執行 .NET 主控台應用程式來產生通知。
訂閱突發新聞的每台設備都會收到您剛剛發送的突發新聞通知。
後續步驟
在本教學課程中,您已將廣播通知傳送至已註冊類別的特定 iOS 裝置。 若要瞭解如何推送當地語系化通知,請繼續閱讀下列教學課程: