Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Xamarinアプリとプッシュ通知

 Xamarinアプリとプッシュ通知

2017/06/17(土) 学生でもわかるXamarin勉強会

Nobuhiro Ito

June 17, 2017
Tweet

More Decks by Nobuhiro Ito

Other Decks in Technology

Transcript

  1. ࣮૷ w 04όʔδϣϯ͝ͱʹҟͳΔ จݙͷࢀߟ࣌ʹ஫ҙʂ  w J04·Ͱ͸ɺϦϞʔτϓογϡͷొ࿥ͷΈ ड৴छผͷొ࿥΋͢Δ  w

    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes w J04Ҏ߱͸ɺ௨஌ͷڐՄͱϦϞʔτϓογϡͷొ࿥͕෼͔Εͨ w UIApplication.SharedApplication.RegisterUserNotificationSettings w UIApplication.SharedApplication.RegisterForRemoteNotification w J04Ҏ߱ɺ6TFS/PUJpDBUJPO'SBNFXPSLʹ෼཭͞Εͨ w UNUserNotificationCenter.Current.RequestAuthorization w UIApplication.SharedApplication.RegisterForRemoteNotification
  2. 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();
 }

  3. public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
 {
 var tokenString

    = BitConverter.ToString(deviceToken.ToArray()).Replace("-", "");
 Console.WriteLine(tokenString);
 
 // ダメ絶対
 // tokenString = deviceToken.ToString().Replace(" ", "");
 } w NSData.ToString͸- (NSString *) descriptionʹϚοϓ͞Ε͍ͯΔ w ͜ͷϝιου͸σόοά༻Ͱग़ྗ͸ෆఆͱ͞Ε͍ͯΔ কདྷมΘΔՄೳੑ΋ඍϨଘ  w ҰํBitConverter.ToString͸AA-BB-CC-00-12-34…ͱ͍͏ܗࣜͰ͋Δͱ
 ϦϑΝϨϯεͰ໌ࣔ͞Ε͍ͯΔ ͜Ε͕ϓογϡτʔΫϯͩʂ
  4. (PPHMF1MBZ4FSWJDFͷ൑ఆ 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;
 }
 }
  5. τʔΫϯͷऔಘ button.Click += delegate
 {
 if (IsPlayServicesAvailable()) 
 {
 Log.Debug("PushNotificationSample",

    $"Push Token is {FirebaseInstanceId.Instance.Token} ");
 }
 }; ͜Ε͕ϓογϡτʔΫϯͩʂ w ࣮ࡍ͸*T1MBZ4FSWJDF"WBJMBCMFͷ൑ఆͰ
 Ϣʔβʔʹ։ൃऀαʔϏεͷߋ৽Λଅͨ͠ΓɺΞϓϦΛڧ੍ऴྃͨ͠Γ͢Δ
  6. *OTUBODF*%3FDFJWFSͷొ࿥ w "OESPJEͷϓογϡτʔΫϯ͸ಥવมΘΔ৔߹͕͋Δ w τʔΫϯͷมߋΛड৴͢ΔαʔϏεΛΞϓϦʹొ࿥͓͔ͯ͠ͳ͚Ε͹ͳΒͳ͍ w "OESPJE.BOJGFTUʹهࡌ <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>
  7. *OTUBODF*%4FSWJDFͷ࣮૷ [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}");
 }
 }
 ϓογϡτʔΫϯ͕ߋ৽͞ΕΔͱ௨஌͞ΕΔ
  8. 

  9. ͦ΋ͦ΋#PMU[&OHJOF͸ w ௒ߴ଎ϓογϡ௨஌Τϯδϯ w ඵؒສσόΠε ࠃ಺࠷଎Ϋϥε  w େྔɾߴ଎ͷ഑৴ཁ݅ʹద߹ w

    ύοέʔδλΠϓ w ϓϥΠϕʔτΫϥ΢υɾΦϯϓϨϛεͳͲ΁ͷల։ w ηΩϡϦςΟϙϦγʔతʹ"41΍"[VSFΛબ୒Ͱ͖ͳ͍৔߹ w εϚʔτϑΥϯ޲͚ "1/T($. ΢Σϒϒϥ΢β޲͚ͷૹ৴ʹରԠ
  10. QSPUPϑΝΠϧͷม׵ w #PMU[&OHJOFఴ෇ͷQSPUPϑΝΠϧΛ·ͱΊΔ w /V(FU͔Β(SQD5PPMTΛμ΢ϯϩʔυ͢Δ
 /V(FU͔ΒOVQLHམͱ͖ͯͯ͠VO[JQʜ $ 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
  11. QSPUPϑΝΠϧͷม׵ w ҎԼͷΑ͏ͳίϚϯυͰม׵ w QSPUPσΟϨΫτϦʹೖ͍ͬͯΔ΋ͷΛ#PMU[&OHJOF3QDϑΥϧμʹల։ $ 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
  12. #PMU[&OHJOFͰͷ௨஌ૹ৴ w $IBOOFMΫϥεͷΠϯελϯεΛੜ੒ w #PMU[(BUFXBZ$MJFOUΛੜ੒ w .FTTBHFΛੜ੒ w 4FOEͰૹ৴ w

    ࣦഊ৘ใɾτʔΫϯมߋ৘ใΛ4USFBN͔Βऔಘ var channel = new Channel("boltzengine.example.com:13009", ChannelCredentials.Insecure);
 var client = new BoltzGateway.BoltzGatewayClient(channel);
  13. ϝοηʔδͷ࡞੒ ϔομ 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
 } ;

  14. ϝοηʔδͷ࡞੒ ϔομ 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
 } ;
 "1/Tൿີ伴ͱূ໌ॻΛಡΈࠐΈ #ZUF4USJOHͰࢦఆ
  15. ϝοηʔδͷ࡞੒ ϔομ 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
 } ;
 "1/Tͷήʔτ΢ΣΠαʔόʔ 4BOECPYͷ৔߹͸HBUFXBZTBOECPYQVTIBQQMFDPN
  16. ϝοηʔδͷ࡞੒ ϔομ 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
 } ;
 '$.ͷ"1*Ωʔͱૹ৴ऀ*%Λࢦఆ
  17. ϝοηʔδͷ࡞੒ ಺༰ message.Payload = @"{""aps"":{""alert"":""Hello Hello""}}";
 message.Parameters = new BoltzEngine.Rpc.Gcm.Parameters();


    message.Parameters.Notification.Add("title", "Hello Hello"); w #PMU[&OHJOFH31$͸ͭͷϝοηʔδͰෳ਺ͷαʔϏεʹૹ৴Մೳ w J04͸1BZMPBE "OESPJE͸1BSBNFUFST 8FC1VTI͸#PEZʹࢦఆ
  18. ϝοηʔδͷૹ৴ 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;
 }
 }
  19. 04͝ͱͷϓογϡ௨஌ͷࠩ J04 "OESPJE 8FC ڐՄཁٻ τʔΫϯͷऔಘ࣌ʹ
 ڐՄμΠΞϩά σϑΥϧτͰڐՄ τʔΫϯ͸ඞͣऔΕΔ τʔΫϯͷऔಘ࣌ʹ


    ڐՄμΠΞϩά αʔόʔͷೝূɾొ࿥ "%1Ͱূ໌ॻൃߦ 'JSFCBTFͰΩʔൃߦ ࣗ෼Ͱ҉߸ԽΩʔΛੜ੒ ௨஌ͷ಺༰ ϑΥʔϚοτʹܾ·Γ͋Γ +40/ܗࣜ ,FZ7BMVFͰ౉͢ ೚ҙͷςΩετ +40/Λྲྀ͢ͷ͕࣮༻త ௨஌ΛτϦΨʔͱͨ͠ಈ࡞ ϑϥάΛཱͯΔͱՄೳ ൃಈ͸ෆ҆ఆ Մೳ Մೳ ୺຤ͷ௨஌දࣔ΋ΞϓϦଆͰ࣮૷ ແޮ୺຤ͷॲཧ ϑΟʔυόοΫαʔϏε΁ ఆظతʹݟʹߦ͘ ૹ৴࣌ʹ൑໌͢Δ ૹ৴࣌ʹ൑໌͢Δ