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

実践 CallKit/PushKit ときどき🐛退治 / iOSDC 2019

monoqlo
September 07, 2019

実践 CallKit/PushKit ときどき🐛退治 / iOSDC 2019

iOSDC JAPAN 2019 2019/09/07 13:30〜 Track E レギュラートーク(30分)

monoqlo

September 07, 2019
Tweet

More Decks by monoqlo

Other Decks in Technology

Transcript

  1. • iOS 10 ͔Β࢖͑ΔϑϨʔϜϫʔΫ • Apple ७ਖ਼ి࿩ΞϓϦͷΑ͏ͳ UI/UX Λ ࣮ݱͰ͖Δ

    • ண৴࣌ʹి࿩ΞϓϦͱಉ౳ͷ UI Λදࣔ • ௨࿩ཤྺʹදࣔɺཤྺ͔Βର৅ΞϓϦΛ ࢦఆͯ͠ൃ৴ • Call Directory Extension • ண৴ڋ൱΍ൃ৴ऀͷࣝผ͕Ͱ͖Δ CallKit
  2. UserNotifications vs. PushKit 6TFS/PUJpDBUJPOT 1VTI,JU Ξϥʔτόοδ ௨஌Ի දࣔͰ͖Δ /POF ஗Ԇ

    ϕετΤϑΥʔτ ʢ࣮֬ʹಧ͘อূ΋ͳ͍ʣ ΑΓ௿஗Ԇ ʢ௨ৗΑΓ΋༏ઌ͞ΕΔʣ ϖΠϩʔυ௕ ,# )551 ,# ΞϓϦ͕ࢮΜͰΔ࣌ ͷڍಈ ಛʹԿ΋ͯ͘͠Εͳ͍ ΞϓϦΛόοΫάϥ΢ϯυ Ͱىಈͯ͘͠ΕΔ
  3. Enhancing VoIP Apps with CallKit - WWDC 2016 - Videos

    - Apple Developer https://developer.apple.com/videos/play/wwdc2016/230/ Speakerbox ͱ͍͏αϯϓϧίʔυ͕͋Γͦ͏ʁ
  4. let configuration = CXProviderConfiguration(localizedName: “App Name”) configuration.includesCallsInRecents = false configuration.maximumCallGroups

    = 1 configuration.maximumCallsPerCallGroup = 1 configuration.iconTemplateImageData = UIImage(named: “AppLogo")!.pngData() self.provider = CXProvider(configuration: configuration) self.provider.setDelegate(self, queue: nil) CXProvider ͷ४උ
  5. extension VoiceCallManager: PKPushRegistryDelegate { func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials:

    PKPushCredentials, for type: PKPushType) { guard type == .voIP else { return } let deviceToken = (pushCredentials.token as NSData).description // ϓογϡ௨஌ड͚औΕΔΑ͏ʹαʔόʔ౉͢ } } } PKPushRegistryDelegate ͷ४උ
  6. extension VoiceCallManager: PKPushRegistryDelegate { func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload:

    PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) { if type == .voIP { // ண৴ը໘Λදࣔ͢Δ // reportNewIncomingCall(with:update:completion:) Λίʔϧ } completion() } } PKPushRegistryDelegate ͷ४උ
  7. extension VoiceCallManager: CXProviderDelegate { func providerDidReset(_ provider: CXProvider) { //

    Ի੠༗ޮԽ } func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { // Ի੠༗ޮԽ } func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { // Ի੠ແޮԽ } } CXProviderDelegate ͷ४උ
  8. extension VoiceCallManager: CXProviderDelegate { func provider(_ provider: CXProvider, perform action:

    CXSetMutedCallAction) { // ϛϡʔτON/OFFॲཧ action.fulfill() } func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) { // Ԡ౴ޙͷॲཧ.͜ͷλΠϛϯάͰ͸·ͩԻ੠ΛແޮԽ͓ͯ͘͠ action.fulfill() } } CXProviderDelegate ͷ४උ
  9. extension VoiceCallManager: CXProviderDelegate { func provider(_ provider: CXProvider, perform action:

    CXStartCallAction) { // ൃ৴ॲཧΛͯ͠CallKitʹ఻͑Δ provider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: Date()) provider.reportOutgoingCall(with: action.callUUID, connectedAt: Date()) action.fulfill() } } CXProviderDelegate ͷ४උ
  10. extension VoiceCallManager: CXProviderDelegate { func provider(_ provider: CXProvider, perform action:

    CXEndCallAction) { // ੾அޙͷॲཧ action.fulfill() } func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) { // อཹON/OFFॲཧ action.fulfill() } } CXProviderDelegate ͷ४උ
  11. let voipRegistry = PKPushRegistry(queue: .main) voipRegistry.delegate = self voipRegistry.desiredPushTypes =

    Set([.voIP]) self.voIPPushRegistry = voipRegistry // ௨ৗ਺ඵҎ಺ʹҎԼͷσϦήʔτϝιου͕ίʔϧ͞ΕΔ // func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) VoIP Push ௨஌ͷొ࿥
  12. let callHandle = CXHandle(type: .generic, value: "໊લ") let startCallAction =

    CXStartCallAction(call: uuid, handle: callHandle) let transaction = CXTransaction(action: startCallAction) self.callController.request(transaction) { error in if let error = error { return } let callUpdate = CXCallUpdate() callUpdate.remoteHandle = callHandle self.provider.reportCall(with: uuid, updated: callUpdate) // CXProviderDelegate ͷ provider(_ provider: CXProvider, perform action: CXStartCallAction) ͕ίʔϧ͞ ΕΔ } ൃ৴͢Δ
  13. let callHandle = CXHandle(type: .generic, value: "ి࿩͔ ͚͖ͯͯΔਓͷ໊લ”) let callUpdate

    = CXCallUpdate() callUpdate.remoteHandle = callHandle // ௨࿩ΛಛఆͰ͖ΔUUIDΛࣄલʹ෷͍ग़͓ͯ͘͠ self.provider.reportNewIncomingCall(with: uuid, update: callUpdate) { error in // Τϥʔ͕ൃੜ͍ͯ͠ͳ͚Ε͹ɺ͜͜ͰԻ੠௨࿩Λ։࢝͢Δ } ண৴ը໘Λදࣔ͢Δ
  14. • Enhancing VoIP Apps with CallKit - WWDC 2016 -

    Videos - Apple Developer https://developer.apple.com/videos/play/wwdc2016/230/ • twilio/voice-quickstart-swift: Twilio Voice Quickstart for iOS with Swift https://github.com/twilio/voice-quickstart-swift ৄ͘͠͸
  15. ূ໌ॻ伴ͷ؅ཧ ೝূ伴Λ ൒Ӭٱతʹ࢖͑Δ ຖ೥ূ໌ॻͷߋ৽͕ඞཁ 6TFS/PUJpDBUJPOT 1VTI,JU Ξϥʔτόοδ ௨஌Ի දࣔͰ͖Δ /POF

    ஗Ԇ ϕετΤϑΥʔτ ʢ࣮֬ʹಧ͘อূ΋ͳ͍ʣ ΑΓ௿஗Ԇ ʢ௨ৗΑΓ΋༏ઌ͞ΕΔʣ ϖΠϩʔυ௕ ,# )551 ,# ΞϓϦ͕ࢮΜͰΔ࣌ ͷڍಈ ಛʹԿ΋ͯ͘͠Εͳ͍ ΞϓϦΛόοΫάϥ΢ϯυ Ͱىಈͯ͘͠ΕΔ
  16. let callHandle = CXHandle(type: .generic, value: "͔͚͖ͯͯΔਓͷ໊લ”) let callUpdate =

    CXCallUpdate() callUpdate.remoteHandle = callHandle callUpdate.supportsDTMF = false callUpdate.supportsHolding = true callUpdate.supportsGrouping = false callUpdate.supportsUngrouping = false callUpdate.hasVideo = false self.provider.reportNewIncomingCall(with: UUID(), update: callUpdate) { error in // Τϥʔ͕ൃੜ͠ͳ͚Ε͹ɺ࣮ࡍ͸͜͜ͰԻ੠௨࿩ Λ։࢝͢Δ }
  17. • CallKit ͷண৴/௨࿩த UI Λ֬ೝ͢Δ͚ͩͳΒ ؆୯ • CXProvider ͷ͜ͷϝιουΛୟ͚ͩ͘ •

    reportNewIncomingCall(with:update:c ompletion:) ௨࿩ͤͣʹ CallKit ͷ UI ͸֬ೝͰ͖Δ
  18. • ௨࿩த UI ͔Βͷૢ࡞ʢ͋ͱͰ௨஌ ΍ ੾அ ͳͲʣ΋͔֬ΊΒΕΔ • UI Λૢ࡞͢Δͱ֤छ

    delegate ϝιου ͕ίʔϧ͞ΕΔͷͰɺ࣮૷͠ͳ͍ or σόοάઐ༻ʹ͓ͯ͘͠ඞཁ͸͋Δ ௨࿩ͤͣʹ CallKit ͷ UI ͸֬ೝͰ͖Δ
  19. <?xml version="1.0" encoding="UTF-8"?> <Response> <Say voice="alice">Thanks for trying our documentation.

    Enjoy!</Say> <Play>http://demo.twilio.com/docs/classic.mp3</ Play> </Response> TwiMLʢthe Twilio Markup Languageʣ http://demo.twilio.com/docs/voice.xml
  20. from twilio.rest import Client account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' auth_token = 'your_auth_token'

    client = Client(account_sid, auth_token) call = client.calls.create( url='http://demo.twilio.com/docs/voice.xml', to=‘client:xxxxxxxxx’, from_='client:debug_call' ) Python Ͱ௨࿩Λൃ৴͢Δ
  21. • ࣗ਎ʹ௨࿩͕͔͔ͬͯ͘Δ API • σόοάը໘͔Β API Λୟ͘ͱ ண৴ • ΞϓϦ͕ऴ͍ྃͯ͠Δঢ়ଶͰண

    ৴΋Ͱ͖ΔΑ͏ʹɺAPI ʹ͸Կ ඵޙʹண৴͢Δ͔ࢦఆͰ͖Δύ ϥϝʔλΛ༻ҙ ண৴ϦΫΤετ API Λ༻ҙ
  22. • provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) => อཹON •

    provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) => อཹOFF อཹ ON/OFF ͷτϦΨʔ
  23. 3. ͳ͔ͥ provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) ͕࣮ߦ͞Εɺอཹ͕ղআ ͞Εͳ͍

    • ࣗ෼Ͱ੾ͬͨ৔߹͸ provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) ͕࣮ߦ͞ΕΔͷͰอཹ͕ղআ͞ ΕΔ ໰୊ൃੜͷৄࡉ
  24. let callHandle = CXHandle(type: .generic, value: "͔͚͖ͯͯΔਓͷ໊લ”) let callUpdate =

    CXCallUpdate() callUpdate.remoteHandle = callHandle callUpdate.supportsDTMF = false callUpdate.supportsHolding = true callUpdate.supportsGrouping = false callUpdate.supportsUngrouping = false callUpdate.hasVideo = false self.provider.reportNewIncomingCall(with: UUID(), update: callUpdate) { error in // Τϥʔ͕ൃੜ͠ͳ͚Ε͹ɺ࣮ࡍ͸͜͜ͰԻ੠௨࿩ Λ։࢝͢Δ }
  25. • CallKit/PushKit Λ࢖͏ͱ७ਖ਼ి࿩ΞϓϦͷ Α͏ͳ UI/UX͕࣮ݱͰ͖Δ • ެࣜαϯϓϧίʔυ͸ͳ͍ͷͰɺTwilio ͷ αϯϓϧίʔυݟΔͷΦεεϝ •

    σόοά͠΍͍͢؀ڥΛ͓ͭͬͯ͘͘ͱḿΔ • CallKit ͷׂࠐ௨࿩όάʢ࢓༷ʣ͸ରॲͯ͠ ͓͘͜ͱ ·ͱΊ
  26. And new this year, it's very important that you know

    that you must report incoming calls with CallKit in the didReceiveIncomingPush callback or your app will be terminated. And, if you repeatedly do this, or if you repeatedly fail not to report an incoming call, the system may stop launching your app for VoIP pushes altogether. WWDCͰͷקࠂ https://developer.apple.com/videos/play/wwdc2019/707/
  27. • ϓογϡ௨஌͕དྷͨΒ CallKit ͷ UI Λදࣔ͠ ͳ͍ͱΞϓϦ͕ࡴ͞ΕΔ • CallKit UI

    දࣔʹ܁Γฦࣦ͠ഊ͢ΔͱɺVoIP ϓογϡ௨஌ͰΞϓϦ͕ىಈ͢Β͠ͳ͘ͳΔ WWDCͰͷקࠂ
  28. • WhatsApp ͳͲɺΤϯυπʔΤϯυ҉߸ԽͷͨΊ ʹ PushKit Λ࢖͍ͬͯΔΞϓϦ΋͋ͬͨ໛༷ • όφʔग़͍ͨ͠ʁ Notification Service

    Extension ࢖͍ͳΑ Prefer a banner? Use standard pushes Notification Service Extension to modify content ϝοηʔδϯάΞϓϦ΁ͷݗ੍ʁ
  29. • Twilio SDK ͸ਖ਼نͷखஈͰ࢖͍ͬͯΔ͚ͲӨڹ ड͚͍ͯΔ • PushKit Λண৴͚ͩͰ͸ͳ͘ɺ௨࿩ΩϟϯηϧͰ ΋࢖͍ͬͯͨͷ͕ݪҼ iOS

    13 & Xcode 11 Breaking Changes – Twilio Support https://support.twilio.com/hc/en-us/articles/ 360035005593-iOS-13-Xcode-11-Breaking-Changes Twilio ແࣄࢮ๢
  30. • Enhancing VoIP Apps with CallKit - WWDC 2016 -

    Videos - Apple Developer https://developer.apple.com/videos/play/wwdc2016/230/ • CallKit | Apple Developer Documentation https://developer.apple.com/documentation/callkit • PushKit | Apple Developer Documentation https://developer.apple.com/documentation/pushkit • Energy Efficiency Guide for iOS Apps: Voice Over IP (VoIP) Best Practices https://developer.apple.com/library/archive/documentation/Performance/ Conceptual/EnergyGuide-iOS/OptimizeVoIP.html References
  31. • Twilio - Communication APIs for SMS, Voice, Video and

    Authentication https://www.twilio.com • Twilioͱ͸ | Twilio for KDDI Web Communications https://twilio.kddi-web.com/availability/ References
  32. • twilio/twilio-voice-ios: Programmable Voice SDK by Twilio https://github.com/twilio/twilio-voice-ios • twilio/voice-quickstart-swift:

    Twilio Voice Quickstart for iOS with Swift https://github.com/twilio/voice-quickstart-swift • PushKit | Apple Developer Documentation https://developer.apple.com/documentation/pushkit • Energy Efficiency Guide for iOS Apps: Voice Over IP (VoIP) Best Practices https://developer.apple.com/library/archive/documentation/Performance/ Conceptual/EnergyGuide-iOS/OptimizeVoIP.html References
  33. • Local and Remote Notification Programming Guide: Creating the Remote

    Notification Payload https://developer.apple.com/library/archive/documentation/ NetworkingInternet/Conceptual/RemoteNotificationsPG/ CreatingtheNotificationPayload.html • Advances in App Background Execution - WWDC 2019 - Videos - Apple Developer https://developer.apple.com/videos/play/wwdc2019/707/ • iOS 13 & Xcode 11 Breaking Changes – Twilio Support https://support.twilio.com/hc/en-us/articles/360035005593-iOS-13-Xcode-11- Breaking-Changes References