Xamarin.iOS 的遠端推播通知 Remote Push Notification - 使用 Azure Notification Hub
本章節將會說明如何透過 Azure Notification Hub 服務,建立起一個具有遠端推播訊息功能的 Android App。
本教學課程示範如何使用 Azure 通知中樞將推播通知傳送至 iOS 應用程式。 您會使用 Apple Push Notification Service (APNS) 建立可接收推播通知的空白 Xamarin.iOS 應用程式。完成之後,您將可使用通知中樞,將推播通知廣播到所有執行您的應用程式的裝置。
在本教學課程中,您會建立/更新程式碼以執行下列工作:
- 產生憑證簽署要求檔案
- 針對推播通知註冊應用程式
- 建立應用程式的佈建設定檔
- 針對 iOS 推播通知設定您的通知中樞
- 傳送測試推播通知
必要條件
- Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費 Azure 帳戶。
- 最新版的 Xcode
- iOS 10 (或更新版本) 相容的裝置
- Apple Developer Program 成員資格。
- Visual Studio for Mac
建立 iOS 佈建設定檔
Apple Push Notification Service (APNS) 使用憑證來驗證您的通知服務。 遵循下列指示來建立必要的推播憑證,以便傳送和接收通知。 如需這些概念的詳細資訊,請參閱 Apple Push Notification Service 官方文件。
產生憑證簽署要求 (CSR) 檔案,這將由 Apple 用來產生簽署的推播憑證。
建立 憑證簽署要求 (CSR) 檔案
- 開啟 [啟動台] 上的 [其他] 資料夾
- 打開 [鑰匙圈存取],並展開 [憑證輔助程式],然後按一下 [從憑證授權要求憑證...]。使用金鑰鏈存取要求新憑證
當 [憑證輔助程式] 視窗顯示出來後,請在 [使用者電子郵件地址] 與 [一般名稱] 填入適當的欄位值,接著勾選 [儲存至磁碟],然後點選 [繼續] 按鈕。
設定合適的 憑證簽署要求 (CSR) 檔案名稱,接著選取要將這個檔案儲存到的目錄位置,在這裡預設為儲存到 [桌面] 資料夾,確認無誤之後,點選 [儲存] 按鈕,將這個檔案儲存取來。
妥善保存 憑證簽署要求 (CSR) 檔案該 憑證簽署要求 (CSR) 檔案 檔案相當的重要,請務必要妥善保存在一個安全的地方
- 此時,憑證輔助程式 已經將 憑證簽署要求 檔案儲存到指定的目錄下,請點選 [完成] 按鈕,結束此作業。
建立 開發環境用的憑證 (Certificates > Development)
- 開啟 Apple Developer 網頁
- 點選右上方的 [Account] 連結
- 輸入 Apple Developer 帳號與密碼,以登入此系統
- 在左方功能清單中,點選 [Certificates, IDs & Profiles] 選項
- 現在將會位於 [Certificates] > [All] 的 [iOS Certificates] 頁面,請點選右上方的 [Add] 新增按鈕
- 選擇 iOS App Development 項目
- 接著點選最下方的 Continue 按鈕
- 現在這個頁面說明什麼是一個 憑證簽署要求 (Certificate Signing Request CSR),並且要如何建立這個檔案,不過,這個 憑證簽署要求 (CSR) 檔案已經於上面程序中產生出來,因此,可以捲動到該頁面最下方,點選 [Continue] 按鈕。
- 此時,需要在這個頁面把 憑證簽署要求 (CSR) 檔案,上傳到 Apple Developer 系統內
- 點選 [Choose File...] 按鈕
- 在顯示出來的選擇檔案對話窗中,切換到 憑證簽署要求 (CSR) 檔案所在的目錄下,選擇這個 憑證簽署要求 (CSR) 檔案
- 點選 [選擇] 按鈕
- 捲動到該頁面最下方,點選 [Continue] 按鈕
- 頁面顯示出 [Your certificate is ready.] 標題,現在可以點選 [Download] 按鈕,下載這個開發憑證到 Mac 電腦上。
- 如同該頁面文字上的描述,剛剛下載下來的檔案,請開啟這個憑證檔案 (檔案名稱為: ios_development.cer),安裝到 Mac 電腦上的 鑰匙圈存取 內。
- 從 [Certificates, IDs & Profiles] 頁面,點選左方的 [Certificates] > [All] 連結,將會看到剛剛建立好的開發環境用的憑證。
建立 新的應用程式識別碼 (App ID)
- 從 [Certificates, IDs & Profiles] 頁面,點選左方的 [Identifiers] > [App IDs] 連結。
- 請點選右上方的 [Add] 新增按鈕
- 在 [Registering an App ID] 頁面,也就是要註冊應用程式識別碼,找到 [App ID Description] 的 [Name] 欄位,在這個欄位內填入這個應用程式的名稱說明內容。
- 在 [App ID Suffix] 區段下, 找到 [Explicit App ID] 這個選項,並且勾選這個選項,找到該選項底下的 [Bundle ID] ,也就是 [明確的應用程式識別碼] 欄位,在這個欄位中輸入該應用程式的明確識別碼,在此,請輸入
com.vulcan.azurenhub
文字字串。 - 在 [App Services] 區段下, 找到 [Push Notifications] 這個選項,請勾選這個選項
- 點選 [Continue] 這個按鈕
- 當出現 [Confirm your App ID] 頁面主題,點選最下方的 [Register] 按鈕
- 當看見 [Registration complete] 畫面,如下圖所示。 按一下 [Done] 按鈕
取得 Azure 通知中樞要用到的 .p12 憑證的檔案
- 從 [Certificates, IDs & Profiles] 頁面,點選左方的 [Identifiers] > [App IDs] 連結,找到剛剛產生的 應用程式識別碼 App ID,點選這個
com.vulcan.azurenhub
應用程式識別碼 - 捲動到下方,找到底部的 [Edit] 按鈕,點選這個 [Edit] 按鈕
- 現在將會切換到 [iOS App ID Settings] 頁面
- 捲到到該頁面最下方,將會看到 [Push Notifications] 這個項目,請找到 [Development Push SSL Certificate] 區段,點選該區段下方的 [Create Certificate...] 按鈕
- 現在這個頁面,[About Creating a Certificate Signing Request (CSR)],將會再度說明什麼是一個 憑證簽署要求 (Certificate Signing Request CSR),以及說明要如何建立這個檔案,不過,這個 憑證簽署要求 (CSR) 檔案已經於上面程序中產生出來,因此,可以捲動到該頁面最下方,點選 [Continue] 按鈕。
- 在 [Generate your certificate] 頁面,點選 [Choose File...] 按鈕,將會顯示選擇檔案對話窗中,切換到 憑證簽署要求 (CSR) 檔案所在的目錄下,選擇這個 憑證簽署要求 (CSR) 檔案
- 點選 [選擇] 按鈕
- 捲動到該頁面最下方,點選 [Continue] 按鈕
- 現在頁面為 [Your certificate is ready] ,請點選 [Download] 按鈕,下載這個憑證到 Mac 電腦上,並且點選 [Done] 按鈕
- 如同該頁面文字上的描述,剛剛下載下來的檔案,請開啟這個憑證檔案 (檔案名稱為: aps_development.cer),安裝到 Mac 電腦上的 鑰匙圈存取 內。
- 開啟 Mac 電腦上的 鑰匙圈存取,點選左下方的 [憑證] 功能選項,從右方清單中,找到剛剛匯入的推播憑證。
- 以滑鼠右擊這個推播憑證, 按一下 [輸出 「Apple Development iOS Push Service: com.vulcan.azurenhub」...] 選項
- 在儲存為欄位中,輸入
azurenhub APNS Push Service
為檔案命名、選取 [個人資訊交換 .p12] 格式,然後按一下 [儲存] 按鈕。 - 請輸入未來要使用這個 個人資訊交換 .p12 檔案時候,需要驗證的密碼,完成後,請點選 [好] 按鈕。
- 現在將會需要輸入 鑰匙圈存取的密鑰,以便匯出動作,請輸入密碼之後,點選 [允許] 按鈕,完成匯出動作。
建立 應用程式的佈建設定檔
- 從 [Certificates, IDs & Profiles] 頁面,點選左方的 [Provisioning] > [All] 連結,
- 請點選右上方的 [Add] 新增按鈕
- 在 [What type of provisioning profile do you need]頁面,選取 [Development] 區段下的 [iOS App Development] 選項,然後點選 [Continue] 按鈕。
- 在 [Select App ID]頁面,從該頁面中間的 [App ID] 下拉選單欄位中,剛剛建立的 App ID,接著點選 [Continue] 按鈕。
- 在 [Select certificates]頁面,選取用於程式碼簽署會用到的開發憑證,然後按一下 [Continue] 按鈕。
- 在 [Select devices]頁面,選取要用來測試的 [裝置],請選取合適的 Device ID ,然後按一下 [Continue] 按鈕。
- 在 [Name this profile generate]頁面,請在 [Profile Name] 欄位,輸入這個 設定檔 Profile 名稱,採此,將會輸入
Azure Notification Hub Demo Profile
,然後按一下 [Continue] 按鈕。 - 在 [Your provisioning profile is ready]頁面,點選 [Download] 按鈕,下載這個設定檔案 (此時,該檔案名稱將會為 Azure_Notification_Hub_Demo_Profile.mobileprovision )
- 當下載完成後,開啟這個設定檔案並安裝在 Xcode 開發電腦上。 然後按一下 [完成] 按鈕。
設定 Azure 通知中樞的 iOS 推播通知設定
由於在前一章節,已經有說明如何建立一個 Azure 通知中樞,並且透過通知中樞可以將訊息推送到 Android 裝置內,因此,在這裡,將會繼續使用之前建立好的 Azure 通知中樞,繼續完成 iOS 推播通知的設定。
- 打開 Azure 入口網站 網頁,使用您的 Microsoft 帳號,登入到 Azure 系統內 。
- 在 Azure 入口網站 左方,點選 [所有資源],當 所有資源群組都出現之後,點選 [azure-notification-hub-lab] 這個資源群組項目
- 在 [azure-notification-hub-lab] 資源群組清單顯示出來之後,找到 類型為 [Notification Hub] 的項目 azure-notification-hub-lab (azure-notification-hub-lab/azure-notification-hub-lab) ,使用滑鼠點擊這個連結。
設定通知中樞的 iOS 設定
- 在左方的 [設定] 區段內,點選 [Apple (APNS)]。
- 在 [Authentication Mode]下,選擇 [Certificate]
- 在 [Upload Certificate] 欄位下,選擇剛剛下載下來的 個人資訊交換 .p12 檔案,也就是 [azurenhub APNS Push Service.p12]。
- 在 [Password] 欄位中,輸入匯出 個人資訊交換 .p12 檔案時候所設定的密碼
- 在 [Application Mode] 欄位,點選 [Sandbox] 選項。只有在您想傳送推播通知給從市集購買應用程式的使用者時,才可使用 [生產] 模式。
- 最後,點選 [Save] 按鈕
設定 Xamarin.iOS 應用程式,並將其連線至通知中樞
在此,將會繼續延續上一章節中建立的 [XFAzureNHub] Xamarin.Forms 專案,請使用 Visual Studio 2017 打開此專案
設定 Xamarin.iOS 專案
- 展開 [XFAzureNHub.iOS] 專案,使用滑鼠雙擊 [Info.plist] 節點
- 在 [應用程式] 標籤頁次,找到 [套件組合識別碼] 欄位,把剛剛設定的 [Bundle ID] 值,也就是
com.vulcan.azurenhub
輸入到這個欄位中。 - 展開 [XFAzureNHub.iOS] 專案,使用滑鼠雙擊 [Entitlements.plist] 節點
- 切換到 [推播通知] 標籤頁次,勾選 [啟用推播通知] 欄位。
安裝相關 NuGet 套件
- 滑鼠右擊 [XFAzureNHub.iOS] 專案的 [參考] 節點,選取 [管理 NuGet 套件] 選項
- 切換到 [瀏覽] 標籤頁次
- 搜尋 [Xamarin.Azure.NotificationHubs.iOS] 套件,安裝到 [XFAzureNHub.iOS] 專案
建立 Constants.cs 類別
- 在 [XFAzureNHub.iOS] 專案內,建立一個 Constants.cs 類別,並定義類別中的下列常數值。其中,[ListenConnectionString] 這個常數,需要到 Azure 通知中樞中,找到 [DefaultListenSharedAccessSignature] 這個欄位值來填入進來,這個欄位值可以從 [azure-notification-hub-lab] 這個通知中樞設定頁面,在左方功能清單的最下方,找到 [Manage] > [Access Policies] 連結,點擊之後,就會在右方視窗中看到 [DefaultListenSharedAccessSignature] 欄位。另外一個 [NotificationHubName] 常數,就是這個 Azure 通知中樞的名稱,也就是 [azure-notification-hub-lab]
Constants.cs
public static class Constants
{
public const string ListenConnectionString = "請在這裡填入 Azure Notification Hub 的 DefaultListenSharedAccessSignature 值";
public const string NotificationHubName = "這裡填入 Azure Notificaion Hub 的名稱";
public const string NotificationTitle = "Azure 通知中樞訊息";
}
修正 AppDelegate 類別
- 打開 [AppDelegate.cs] 檔案,在最前面加入底下的命名空間參考
AppDelegate.cs
using WindowsAzure.Messaging;
using UserNotifications;
在 [AppDelegate] 類別中,宣告 SBNotificationHub 的執行個體
AppDelegate.cs
private SBNotificationHub Hub { get; set; }
在 [AppDelegate] 類別中,更新 FinishedLaunching() 以符合下列程式碼
AppDelegate.cs
public override bool FinishedLaunching(UIApplication app, SDictionary options)
{
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
UNUserNotificationCenter.Current.RequestAuthorization
(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Sound,
(granted, error) =>
{
if (granted)
InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
});
}
else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App(new iOSInitializer()));
return base.FinishedLaunching(app, options);
}
- 在 AppDelegate.cs 中覆寫 RegisteredForRemoteNotifications() 方法
AppDelegate.cs
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);
Hub.UnregisterAllAsync(deviceToken, (error) => {
if (error != null)
{
System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
return;
}
NSSet tags = null; // create tags if you want
Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) => {
if (errorCallback != null)
System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
});
});
}
- 在 AppDelegate.cs 中覆寫 ReceivedRemoteNotification() 方法
AppDelegate.cs
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
{
ProcessNotification(userInfo, false);
}
- 在 AppDelegate.cs 中建立 ProcessNotification() 方法
AppDelegate.cs
void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
{
// Check to see if the dictionary has the aps key. This is the notification payload you would have sent
if (null != options && options.ContainsKey(new NSString("aps")))
{
//Get the aps dictionary
NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
string alert = string.Empty;
//Extract the alert text
// NOTE: If you're using the simple alert by just specifying
// " aps:{alert:"alert msg here"} ", this will work fine.
// But if you're using a complex alert with Localization keys, etc.,
// your "alert" object from the aps dictionary will be another NSDictionary.
// Basically the JSON gets dumped right into a NSDictionary,
// so keep that in mind.
if (aps.ContainsKey(new NSString("alert")))
alert = (aps[new NSString("alert")] as NSString).ToString();
//If this came from the ReceivedRemoteNotification while the app was running,
// we of course need to manually process things like the sound, badge, and alert.
if (!fromFinishedLaunching)
{
//Manually show an alert
if (!string.IsNullOrEmpty(alert))
{
UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null);
avAlert.Show();
}
}
}
}
開始進行測試
- 滑鼠右擊專案 [XFAzureNHub.iOS],點選 [設定為起始專案] 選項
- 選擇在 iPhone 裝置上來執行這個 [XFAzureNHub.iOS] 專案
codesign 授權在建置或者執行的時候,將會使用開發者憑證進行程式碼簽名,此時,在 Mac 電腦上將會出現上述對話窗,請輸入登入的密碼並且允許程式碼簽名。
- 當這個 App 在 iPhone 上第一次啟動之後,將會看到如下圖畫面,請點選 [允許] 按鈕
- 在 Azure 通知中樞 (azure-notification-hub-lab) 的網頁上,點選 [Test Send] 按鈕
- 切換 [Platform] 欄位值為 [Apple]
- 點選下方的 [Send] 按鈕
- 當最下方的 [Result] 列表出現新的紀錄,則表示剛剛的通知推播已經傳送到遠端裝置上了若這個應用程式不在前景執行中,也是可以收到來自遠端的通知推播的