xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi •...

69
Xamarin アプリとプッシュ通知 Nobuhiro Ito 2017/06/17 学生でもわかるXamarin勉強会

Upload: others

Post on 23-Aug-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Xamarin アプリとプッシュ通知Nobuhiro Ito 2017/06/17 学生でもわかるXamarin勉強会

Page 2: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

自己紹介

• 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア • 兼 新規事業部 BoltzEngine プロダクトオーナー

• 主にスマートフォンアプリの設計・開発を担当。最近はマネージメントも。 • iOS (Swift, Objective-C) / Android (Java) / Xamarin (C#) / Web (PHP)

Page 3: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •
Page 4: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

名古屋でイベントやってます

• Mobile Act NAGOYA • フェンリル名古屋支社メンバーが主催 • 隔月くらいで開催中 (直近は昨日!!) • https://mobileactnagoya.connpass.com/

Page 5: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

サマーインターン開催予定• プロジェクト研修で使われている課題で、実際の業務の流れを体験できます • エンジニア向け • 2017/08/28 - 09/01 : 大阪本社

• 2017/09/04 - 09/08 : 東京支社・島根支社・名古屋支社 • デザイナー向け • 2017/08/28 - 09/01 : 大阪本社・東京支社

• 詳細は来週公開予定 @fenrir_recruit をフォローお願いします。

Page 6: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知とは

• ユーザーがアプリから離れていても、端末・ブラウザへメッセージなどの通知を送る仕組みのこと。新着情報・更新情報などをユーザーに提供することができる。

• タイマー・ジオフェンスでアプリ単体で完結する「ローカルプッシュ」と サーバーからサービス提供者側が送信する「リモートプッシュ」がある • 「プッシュ通知」というとリモートプッシュのことを言ってる場合が多い。この発表でも基本的にリモートプッシュのことを指します。

Page 7: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知の重要性

• ユーザーに価値のある情報を即時に届けることができる

• アプリをユーザーに使ってもらう習慣づけをすることができる

• プッシュ通知を許可したアプリは起動回数や継続率が高くなる

参考: アプリユーザーをアクティブにする!専門家が教える「プッシュ通知」5つの真実と間違い。D2CRアプリセミナー http://appmarketinglabo.net/push-livepass/

Page 8: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

Page 9: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

トークン要求

Page 10: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

トークン要求

トークン返却

Page 11: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

トークン要求

トークン返却

トークン登録

Page 12: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

Page 13: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

メッセージ送信 (認証+トークン+メッセージ)

Page 14: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

メッセージ送信 (認証+トークン+メッセージ)

メッセージ配信

Page 15: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知のしくみ

APNs / FCMサービス提供者の サーバー

アプリ

メッセージ送信 (認証+トークン+メッセージ)

メッセージ配信

! メッセージが届きました

Page 16: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

iOS でのプッシュ通知実装

Page 17: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Apple への登録• Apple Developer Program へ App ID を登録する必要がある • App ID の登録 • APNs 証明書の発行 • プロファイルの作成

Page 18: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

App ID の登録

Page 19: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

App ID の登録

Page 20: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

App ID の登録

Page 21: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

APNs 証明書の発行• App ID 登録後の画面に表示される • ビルドによって使う証明書が異なり、接続先も異なる • Debug ビルド時、Sandbox • Release ビルド時、Production

Page 22: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

詳しくは• BoltzEngine サポートページをご覧ください • APNs を使う iOS アプリのビルドに必要な契約・各種証明書の準備をするにはhttps://www.fenrir-inc.com/jp/boltzengine/support/ios_certificates/

Page 23: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

実装• OS バージョンごとに異なる (文献の参考時に注意!)

• iOS 7 までは、リモートプッシュの登録のみ (受信種別の登録もする) • UIApplication.SharedApplication.RegisterForRemoteNotificationTypes

• iOS 8 以降は、通知の許可とリモートプッシュの登録が分かれた • UIApplication.SharedApplication.RegisterUserNotificationSettings • UIApplication.SharedApplication.RegisterForRemoteNotification

• iOS 10 以降、UserNotification Framework に分離された • UNUserNotificationCenter.Current.RequestAuthorization • UIApplication.SharedApplication.RegisterForRemoteNotification

Page 24: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

ということは• OSバージョンごとに使用する方法を使い分ける必要がある • 使っている OS で実装されていない API 叩くとクラッシュ • iOS 10 以降にできたら最高 • iOS 7 はさすがにもうないでしょう。 • iOS 9 と iOS 10 の共存は現段階ではしかたがない場面多そうUIDevice.CurrentDevice.CheckSystemVersion でチェックするほかなし

Page 25: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

private async void RequestPushNotificationAuthorization(){ if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) { var result = await UNUserNotificationCenter.Current.RequestAuthorizationAsync( UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound); if (result.Item1) { UIApplication.SharedApplication.RegisterForRemoteNotifications(); } } else { var settings = UIUserNotificationSettings.GetSettingsForTypes( UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, null); UIApplication.SharedApplication.RegisterUserNotificationSettings(settings); }}public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings){ UIApplication.SharedApplication.RegisterForRemoteNotifications();}

Page 26: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken){ var tokenString = BitConverter.ToString(deviceToken.ToArray()).Replace("-", ""); Console.WriteLine(tokenString); // ダメ絶対 // tokenString = deviceToken.ToString().Replace(" ", "");}

• NSData.ToString は - (NSString *) description にマップされている

• このメソッドはデバッグ用で出力は不定とされている(将来変わる可能性も微レ存)

• 一方 BitConverter.ToString は AA-BB-CC-00-12-34… という形式であるとリファレンスで明示されている

これがプッシュトークンだ!

Page 27: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Android でのプッシュ通知実装

Page 28: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録• Firebase で Sender ID と Server API Key を作る • https://console.firebase.google.com/

Page 29: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 30: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 31: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 32: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 33: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 34: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Firebase の登録

Page 35: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

NuGet パッケージの導入• 以下の NuGet パッケージを導入する • Xamarin.GooglePlayServices.Base • Xamarin.Firebase.Messaging

• Firebase の設定中に作成されたgoogle-services.json をプロジェクトに追加 ビルドアクションを GoogleServicesJson に変更 • 出てこなかったら VSMac 再起動

Page 36: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Google Play Service の判定public bool IsPlayServicesAvailable(){ int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this); if (resultCode == ConnectionResult.Success) { return true; } if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode)) { // ユーザーの操作によって解決できる問題の場合 (Google Play 開発者サービスが古いなど) return false; } else { // Google Play 開発者サービスが入っていない端末の場合 return false; }}

Page 37: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

トークンの取得button.Click += delegate{ if (IsPlayServicesAvailable()) { Log.Debug("PushNotificationSample", $"Push Token is {FirebaseInstanceId.Instance.Token} "); }}; これがプッシュトークンだ!

• 実際は IsPlayServiceAvailable の判定でユーザーに開発者サービスの更新を促したり、アプリを強制終了したりする

Page 38: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Instance ID Receiver の登録• Android のプッシュトークンは突然変わる場合がある • トークンの変更を受信するサービスをアプリに登録しておかなければならない • AndroidManifest に記載<application …> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" /> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="${applicationId}" /> </intent-filter> </receiver></application>

Page 39: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

Instance ID Service の実装

[Service][IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]public class AppInstanceIdService : FirebaseInstanceIdService{ public override void OnTokenRefresh() { var refreshedToken = FirebaseInstanceId.Instance.Token; Log.Debug(Log.Debug("PushNotificationSample", $"Push Token is {FirebaseInstanceId.Instance.Token}"); }} プッシュトークンが更新されると通知される

Page 40: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

通知の送信

Page 41: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

ライブラリの選定• プッシュの API ってわりとややこしい。 サーバーサイドにどんな言語を使うかで変わってくる。

• C# を使うなら PushSharp という選択肢か。 • https://github.com/Redth/PushSharp

• 言語 + APNs / GCM で検索してみよう

• Firebase べったりになるなら、Firebase の管理画面でやるというのも一案

Page 42: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

PushSharp を使った送信https://github.com/Redth/PushSharp#sample-usage

Page 43: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

!

Page 44: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •
Page 45: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

BoltzEngine で送ってみよう有償製品なんでちょっと申し訳ないですが…

Page 46: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

そもそもBoltzEngineは• 超高速プッシュ通知エンジン • 秒間 3.5 万デバイス (国内最速クラス) • 大量・高速の配信要件に適合

• パッケージタイプ • プライベートクラウド・オンプレミスなどへの展開 • セキュリティポリシー的に ASP や Azure を選択できない場合

• スマートフォン向け (APNs/GCM) ウェブブラウザ向け の送信に対応

Page 47: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

https://www.fenrir-inc.com/jp/boltzengine/

Page 48: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

BoltzEngine への接続• BoltzEngine 本体は送信のみを担当。配信管理は別途用意します。 • 独自開発する場合は gRPC / HTTP / CSV などで送信可能

Page 49: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

標準の配信管理機能標準の配信管理機能・リファレンス実装として BoltzMessenger を用意

Page 50: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

BoltzEngine への接続• BoltzEngine 本体は送信のみを担当。配信管理は別途用意します。 • 独自開発する場合は gRPC / HTTP / CSV などで送信可能

Page 51: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

BoltzEngine への接続• BoltzEngine 本体は送信のみを担当。配信管理は別途用意します。 • 独自開発する場合は gRPC / HTTP / CSV などで送信可能

Page 52: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •
Page 53: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

gRPC• Google が公開した Google 内でも使われている RPC フレームワーク • Protocol Buffer から各言語向けのライブラリを生成するので、様々な言語から接続できる

• HTTP/2 が使われている

• BoltzEngine では 2016 年 6 月の 2.0 から対応

• それまでの Go の net/rpc に代わり標準 API となりつつある

• BoltzEngine への接続は Go, JavaScript, Ruby, C# で実績あり

Page 54: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

C# で gRPC を使う

• proto ファイルの変換 • NuGet パッケージのインストール • コードの記述 • 今のところ Xamarin.Mac はダメそう。.NET Framework 4.6 がいいかと。

Page 55: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

protoファイルの変換• BoltzEngine 添付の proto ファイルをまとめる • NuGet から Grpc.Tools をダウンロードする(NuGet から nupkg 落としてきて unzip…)

$ temp_dir=packages/Grpc.Tools.1.3.6/tmp $ curl_url=https://www.nuget.org/api/v2/package/Grpc.Tools/ $ mkdir -p $temp_dir && cd $temp_dir && curl -sL $curl_url > tmp.zip; unzip tmp.zip \ && cd .. && cp -r tmp/tools . && rm -rf tmp && cd ../.. $ chmod +x packages/Grpc.Tools.1.3.6/tools/macosx_x64/protoc $ chmod +x packages/Grpc.Tools.1.3.6/tools/macosx_x64/grpc_csharp_plugin

Page 56: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

protoファイルの変換• 以下のようなコマンドで変換 • proto ディレクトリに入っているものを BoltzEngine.Rpc フォルダに展開

$ mkdir BoltzEngine.Rpc $ packages/Grpc.Tools.1.3.6/tools/macosx_x64/protoc \ --plugin=protoc-gen-grpc=packages/Grpc.Tools.1.3.6/tools/macosx_x64/grpc_csharp_plugin --csharp_out BoltzEngine.Rpc --grpc_out BoltzEngine.Rpc \ -Iprotos protos/*.proto

Page 57: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

NuGet パッケージのインストール

• プロジェクトに以下の NuGet パッケージをインストール • Grpc • Google.Protobuf

• proto ファイルから変換した .cs ファイルも追加する

Page 58: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

BoltzEngine での通知送信• Channel クラスのインスタンスを生成 • BoltzGatewayClient を生成

• Message を生成 • Send で送信 • 失敗情報・トークン変更情報を Stream から取得

var channel = new Channel("boltzengine.example.com:13009", ChannelCredentials.Insecure);var client = new BoltzGateway.BoltzGatewayClient(channel);

Page 59: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (ヘッダ)var cert = File.ReadAllText("cert.pem");var key = File.ReadAllText("key.pem");var message = new Message{ ApnsHeader = new BoltzEngine.Rpc.Apns.Header() { Address = "gateway.push.apple.com:2195", KeyPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(key), CertPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(cert), }, GcmHeader = new BoltzEngine.Rpc.Gcm.Header() { RequestURL = "https://fcm.googleapis.com/fcm/send", ServerKey = “AAAAw…”, SenderID = "825337918540", }, Priority = Priority.High, BandWidth = 0} ;

Page 60: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (ヘッダ)var cert = File.ReadAllText("cert.pem");var key = File.ReadAllText("key.pem");var message = new Message{ ApnsHeader = new BoltzEngine.Rpc.Apns.Header() { Address = "gateway.push.apple.com:2195", KeyPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(key), CertPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(cert), }, GcmHeader = new BoltzEngine.Rpc.Gcm.Header() { RequestURL = "https://fcm.googleapis.com/fcm/send", ServerKey = “AAAAw…”, SenderID = "825337918540", }, Priority = Priority.High, BandWidth = 0} ;

APNs 秘密鍵と証明書を読み込み

ByteString で指定

Page 61: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (ヘッダ)var cert = File.ReadAllText("cert.pem");var key = File.ReadAllText("key.pem");var message = new Message{ ApnsHeader = new BoltzEngine.Rpc.Apns.Header() { Address = "gateway.push.apple.com:2195", KeyPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(key), CertPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(cert), }, GcmHeader = new BoltzEngine.Rpc.Gcm.Header() { RequestURL = "https://fcm.googleapis.com/fcm/send", ServerKey = “AAAAw…”, SenderID = "825337918540", }, Priority = Priority.High, BandWidth = 0} ;

APNs のゲートウェイサーバー Sandbox の場合は gateway.sandbox.push.apple.com

Page 62: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (ヘッダ)var cert = File.ReadAllText("cert.pem");var key = File.ReadAllText("key.pem");var message = new Message{ ApnsHeader = new BoltzEngine.Rpc.Apns.Header() { Address = "gateway.push.apple.com:2195", KeyPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(key), CertPEMBlock = Google.Protobuf.ByteString.CopyFromUtf8(cert), }, GcmHeader = new BoltzEngine.Rpc.Gcm.Header() { RequestURL = "https://fcm.googleapis.com/fcm/send", ServerKey = “AAAAw…”, SenderID = "825337918540", }, Priority = Priority.High, BandWidth = 0} ;

FCM の API キーと送信者 ID を指定

Page 63: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (内容)

message.Payload = @"{""aps"":{""alert"":""Hello Hello""}}";message.Parameters = new BoltzEngine.Rpc.Gcm.Parameters();message.Parameters.Notification.Add("title", "Hello Hello");

• BoltzEngine gRPC は 1 つのメッセージで複数のサービスに送信可能 • iOS は Payload, Android は Parameters, WebPush は Body に指定

Page 64: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの作成 (送り先)

• 各プラットフォームのトークンの前に、数字を結合して渡す • BoltzEngine gRPC の仕様上必要な操作で、他のライブラリを使う時は不要 • iOS は 1, Android は 2, WebPush は 4

message.Tokens.Add("1" + “126ae202b2d51…");message.Tokens.Add("2" + “cTSHJ6XaN4Y:APA91bH…");

Page 65: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

メッセージの送信var streamingCall = client.Send(message);while (await streamingCall.ResponseStream.MoveNext(CancellationToken.None)){ var ev = streamingCall.ResponseStream.Current; switch (ev.EventCase) { case Event.EventOneofCase.Failed: Console.WriteLine($"Failed: {ev.Failed.Token} reason: {ev.Failed.Kind} "); break; case Event.EventOneofCase.Renewed: Console.WriteLine($"Renewed: {ev.Renewed.RecentToken} to {ev.Renewed.LatestToken} "); break; }}

Page 66: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

今回お話ししなかったこと

• サーバー上でのトークンの取り扱い • 無効・更新トークンの取り扱い • コンテンツ付きプッシュ • プッシュをトリガーしたデータ更新・バックグラウンド動作 • 他

Page 67: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

プッシュ通知の仕組みを理解するとより活用できます

プッシュ通知を有効に利用して アプリをより魅力的にしましょう

Page 68: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

参考

Page 69: Xamarin アプリとプッシュ通知...自己紹介 • 伊藤 伸裕 @iseebi • フェンリル株式会社 アプリケーション共同開発部 チーフエンジニア •

OSごとのプッシュ通知の差

iOS Android Web

許可要求 トークンの取得時に許可ダイアログ

デフォルトで許可 (トークンは必ず取れる)

トークンの取得時に許可ダイアログ

サーバーの認証・登録 ADPで証明書発行 Firebaseでキー発行 自分で暗号化キーを生成

通知の内容 フォーマットに決まりあり JSON形式 Key/Value で渡す 任意のテキスト

JSONを流すのが実用的

通知をトリガーとした動作 フラグを立てると可能 発動は不安定

可能 可能 端末の通知表示もアプリ側で実装

無効端末の処理 フィードバックサービスへ 定期的に見に行く 送信時に判明する 送信時に判明する