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

対話を頑張らなくても作れるSiri Shortcuts向けIntents App Extension

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

対話を頑張らなくても作れるSiri Shortcuts向けIntents App Extension

Avatar for Maika Yamada

Maika Yamada

August 27, 2021
Tweet

More Decks by Maika Yamada

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ w ໌౉ຑҥՖ w 5XJUUFS!N@ZBNBEB w 4UVEZQMVT *OD w ʙ

    w ࣄ຿৬ˠ4*FSˠݱࡏ w ϞόΠϧΫϥΠΞϯτάϧʔϓॴଐJ04&OHJOFFS w J04%$ʹͯҎԼͷςʔϚͰ-5΁ొஃ w J04ʹ͓͚Δ4JSJ4IPSUDVUT࠷খ࣮૷ʴЋ
  2. ͜ͷτʔΫͰ఻͍͑ͨ͜ͱ w ର࿩ͷઃܭΛ͖ͪΜͱ͠ͳͯ͘΋ɺ࣮༻ʹ଱͑͏Δ4JSJ4IPSUDVUT͸࡞ΕΔ w ͨͩ͠ɺϢʔβʔʹΤϥʔͱ஌ΒͤΔέʔε͸పఈతʹ໢ཏͨ͠΄͏͕਌੾ w 4JSJ4IPSUDVUTͷ࣮૷ࣗମ͸೉͘͠ͳ͍ʂ w 9DPEF্Ͱ͔͠։͚ͳ͍ઐ༻ϑΝΠϧ JOUFOUEFOJ

    fi UJPO Λ༻͍Δඞཁ͕͋ Δ͕ɺ։ൃऀ͕ؾΛݣͬͯॻ͘ιʔείʔυͷྔ͸গͳΊ w 88%$ͷಈըΛ؍ͳ͕Β࣮૷͕໘౗ͩͬͨΤϥʔέʔε࣮૷ͳͲΛൃදࢿ ྉʹ٧ΊࠐΜͩͷͰɺօ༷ͷ4JSJ4IPSUDVUT࣮૷࣌ʹ໾ʹཱͯ͹خ͍͠
  3. ΞδΣϯμ w 4UVEZQMVTͰϦϦʔεͨ͠ษڧه࿥Λೖྗ͢Δ4JSJ4IPSUDVUT֓ཁ w 4JSJ4IPSUDVUTͰૢ࡞Λड͚෇͚ΔΞΫγϣϯͷબఆ w ର࿩ͷઃܭ w ΞΫγϣϯຖʹೖྗΛड͚෇͚Δύϥϝʔλઃܭ w

    ೖྗ͞ΕͨύϥϝʔλͷΤϥʔॲཧઃܭʴ࣮૷ྫ w ԡ͓͖͍࣮͑ͯͨ͞૷Λ঺հ w ΞΫγϣϯ׬ྃޙɺΞϓϦʹભҠͯ͠΍Γ͍ͨ͜ͱ͕͋Δ৔߹ͷ࣮૷
  4. 4JSJ4IPSUDVUTར༻ঢ়گ ˞೥݄೔ʙ݄೔࣌఺ w ษڧه࿥ؔ࿈ͷૢ࡞ΛγϣʔτΧοτͰ࣮ߦͨ͠ w ճ਺ɿ ճ w ਓ਺ɿ ਓ

    ˞ಋೖࡁΈͷ'JSFCBTF"OBMZUJDTͰ͸ϝΠϯλʔήοτະىಈͩͱΠϕϯτ͕ ૹ৴Ͱ͖ͳ͔ͬͨͨΊɺγϣʔτΧοτ࣮ߦ࣌ʹϩάΛϩʔΧϧ%#΁อଘͯ͠ ࣍ճΞϓϦىಈ࣌ʹҰׅૹ৴ͯ͠ूܭ ೥݄·Ͱͷ࣮૷౰࣌
  5. ΞδΣϯμ w 4UVEZQMVTͰϦϦʔεͨ͠ษڧه࿥Λೖྗ͢Δ4JSJ4IPSUDVUT֓ཁ w 4JSJ4IPSUDVUTͰૢ࡞Λड͚෇͚ΔΞΫγϣϯͷબఆ w ର࿩ͷઃܭ w ΞΫγϣϯຖʹೖྗΛड͚෇͚Δύϥϝʔλઃܭ w

    ೖྗ͞ΕͨύϥϝʔλͷΤϥʔॲཧઃܭʴ࣮૷ྫ w ԡ͓͖͍࣮͑ͯͨ͞૷Λ঺հ w ΞΫγϣϯ׬ྃޙɺΞϓϦʹભҠͯ͠΍Γ͍ͨ͜ͱ͕͋Δ৔߹ͷ࣮૷
  6. ରԠͨ͠ૢ࡞ w ษڧͨ͜͠ͱΛه࿥͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰετοϓ΢ΥονͷܭଌΛ։࢝͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰλΠϚʔͷܭଌΛ։࢝͢Δ w ετοϓ΢ΥονͷܭଌΛҰ࣌ఀࢭ͢Δ w

    λΠϚʔͷܭଌΛҰ࣌ఀࢭ͢Δ w ετοϓ΢ΥονͷܭଌΛ࠶։͢Δ w λΠϚʔͷܭଌΛ࠶։͢Δ w ετοϓ΢ΥονͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w λΠϚʔͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w ετοϓ΢ΥονͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ w λΠϚʔͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ
  7. ରԠͨ͠ૢ࡞ w ษڧͨ͜͠ͱΛه࿥͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰετοϓ΢ΥονͷܭଌΛ։࢝͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰλΠϚʔͷܭଌΛ։࢝͢Δ w ετοϓ΢ΥονͷܭଌΛҰ࣌ఀࢭ͢Δ w

    λΠϚʔͷܭଌΛҰ࣌ఀࢭ͢Δ w ετοϓ΢ΥονͷܭଌΛ࠶։͢Δ w λΠϚʔͷܭଌΛ࠶։͢Δ w ετοϓ΢ΥονͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w λΠϚʔͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w ετοϓ΢ΥονͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ w λΠϚʔͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ
  8. ରԠͨ͠ૢ࡞ w ษڧͨ͜͠ͱΛه࿥͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰετοϓ΢ΥονͷܭଌΛ։࢝͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰλΠϚʔͷܭଌΛ։࢝͢Δ w ετοϓ΢ΥονͷܭଌΛҰ࣌ఀࢭ͢Δ w

    λΠϚʔͷܭଌΛҰ࣌ఀࢭ͢Δ w ετοϓ΢ΥονͷܭଌΛ࠶։͢Δ w λΠϚʔͷܭଌΛ࠶։͢Δ w ετοϓ΢ΥονͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w λΠϚʔͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w ετοϓ΢ΥονͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ w λΠϚʔͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ ͍ͬͺ͍͋Γ͗ͯ͢ ԿΛ࢖͑͹΍Γ͍ͨ͜ͱ͕Ͱ͖Δͷ͔ ෼͔Βͳ͍ϓϥʂ
  9. w ษڧͨ͜͠ͱΛه࿥͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰετοϓ΢ΥονͷܭଌΛ։࢝͢Δ w ͜Ε͔Βษڧ͢ΔڭࡐͰλΠϚʔͷܭଌΛ։࢝͢Δ w ετοϓ΢ΥονͷܭଌΛҰ࣌ఀࢭ͢Δ w λΠϚʔͷܭଌΛҰ࣌ఀࢭ͢Δ

    w ετοϓ΢ΥονͷܭଌΛ࠶։͢Δ w λΠϚʔͷܭଌΛ࠶։͢Δ w ετοϓ΢ΥονͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w λΠϚʔͰܭଌதͷ࣌ؒΛ֬ೝ͢Δ w ετοϓ΢ΥονͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ w λΠϚʔͰͷܭଌΛ׬ྃ͠ɺษڧΛه࿥͢Δ
  10. ΞδΣϯμ w 4UVEZQMVTͰϦϦʔεͨ͠ษڧه࿥Λೖྗ͢Δ4JSJ4IPSUDVUT֓ཁ w 4JSJ4IPSUDVUTͰૢ࡞Λड͚෇͚ΔΞΫγϣϯͷબఆ w ର࿩ͷઃܭ w ΞΫγϣϯຖʹೖྗΛड͚෇͚Δύϥϝʔλઃܭ w

    ೖྗ͞ΕͨύϥϝʔλͷΤϥʔॲཧઃܭʴ࣮૷ྫ w ԡ͓͖͍࣮͑ͯͨ͞૷Λ঺հ w ΞΫγϣϯ׬ྃޙɺΞϓϦʹભҠͯ͠΍Γ͍ͨ͜ͱ͕͋Δ৔߹ͷ࣮૷
  11. ษڧه࿥ͷೖྗͰड͚෇͚͍ͯΔύϥϝʔλ w ษڧ։࢝࣌ࠁɹˠΞΫγϣϯ࣮ߦ࣌ͷ೔࣌Λࣗಈతʹೖྗ w ڭࡐ w ษڧ࣌ؒ w ֶशྔ w

    ߹ܭPSൣғ w ϝϞ w ը૾ɹˠ୺຤ͷը໘ΛݟΔૢ࡞͕ඞਢͰຊ຤స౗ɺ౤ߘޙʹޙ෇͚ՄೳͳͷͰͦͪΒͰରԠΛ͓ئ͍ w 5XJUUFSͷڞ༗εςʔλεɹˠલճͷ0/0''εςʔλεΛҾ͖ܧ͗ ΞϓϦը໘Ͱड͚෇͚ΔΑΓɺՄೳͳݶΓ࡟ݮ
  12. "QQMF͓͢͢Ίઃܭͷ௨Γͷ৔߹ ษڧه࿥ͷ౤ߘɾܭଌ׬ྃ࣌ʹ͸ҎԼͷΞΫγϣϯΛ४උ w ษڧ࣌ؒΛه࿥ w ڭࡐ ೚ҙ  w ษڧ࣌ؒ

    ඞਢ  w ษڧྔ w ษڧྔΛه࿥ w ڭࡐ ඞਢ  w ษڧ࣌ؒ ೚ҙ  w ษڧྔ ඞਢ w ษڧ࣌ؒͱษڧྔΛه࿥ w ڭࡐ ඞਢ  w ษڧྔ ඞਢ  w ษڧ࣌ؒ ඞਢ
  13. 4UVEZQMVTͷษڧه࿥ػೳΞΫγϣϯ w ೖྗ͞Εͨ಺༰ͰษڧΛه࿥͢Δ w ษڧه࿥ͷετοϓ΢ΥονΛ։࢝ w ษڧه࿥ͷλΠϚʔΛ։࢝ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛҰ࣌ఀࢭ w

    ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ࠶։ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ׬ྃ w ܭଌதͷษڧه࿥Λ֬ೝ ษڧ࣌ؒ ษڧྔ ษڧ࣌ؒͱษڧྔ ษڧ࣌ؒ ษڧ࣌ؒͱษڧྔ
  14. ରԠͨ͠ૢ࡞ w ೖྗ͞Εͨ಺༰ͰษڧΛه࿥͢Δ w ษڧه࿥ͷετοϓ΢ΥονΛ։࢝ w ษڧه࿥ͷλΠϚʔΛ։࢝ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛҰ࣌ఀࢭ w

    ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ࠶։ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ׬ྃ w ܭଌதͷษڧه࿥Λ֬ೝ ษڧ࣌ؒ ษڧྔ ษڧ࣌ؒͱษڧྔ ษڧ࣌ؒ ษڧ࣌ؒͱษڧྔ ྨࣅΞΫγϣϯଟ਺ ˠϢʔβʔ͕ࠞཚͦ͠͏ ˠ"QQMF͓͢͢ΊઃܭΛ΋ͱʹ࣮૷͸அ೦
  15. ରԠͨ͠ૢ࡞ w ೖྗ͞Εͨ಺༰ͰษڧΛه࿥͢Δ w ษڧه࿥ͷετοϓ΢ΥονΛ։࢝ w ษڧه࿥ͷλΠϚʔΛ։࢝ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛҰ࣌ఀࢭ w

    ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ࠶։ w ษڧه࿥ͷετοϓ΢ΥονɾλΠϚʔΛ׬ྃ w ܭଌதͷษڧه࿥Λ֬ೝ ษڧ࣌ؒ ษڧྔ ษڧ࣌ؒͱษڧྔ ษڧ࣌ؒ ษڧ࣌ؒͱษڧྔ zର࿩ΛؤுΒͳͯ͘΋z ࣮༻ʹ଱͑͏Δ4JSJ4IPSUDVUT͸࡞ΕΔ ྨࣅΞΫγϣϯଟ਺ ˠϢʔβʔ͕ࠞཚͦ͠͏ ˠ"QQMF͓͢͢ΊઃܭΛ΋ͱʹ࣮૷͸அ೦
  16. ΞδΣϯμ w 4UVEZQMVTͰϦϦʔεͨ͠ษڧه࿥Λೖྗ͢Δ4JSJ4IPSUDVUT֓ཁ w 4JSJ4IPSUDVUTͰૢ࡞Λड͚෇͚ΔΞΫγϣϯͷબఆ w ର࿩ͷઃܭ w ΞΫγϣϯຖʹೖྗΛड͚෇͚Δύϥϝʔλઃܭ w

    ೖྗ͞ΕͨύϥϝʔλͷΤϥʔॲཧઃܭʴ࣮૷ྫ w ԡ͓͖͍࣮͑ͯͨ͞૷Λ঺հ w ΞΫγϣϯ׬ྃޙɺΞϓϦʹભҠͯ͠΍Γ͍ͨ͜ͱ͕͋Δ৔߹ͷ࣮૷
  17. ύϥϝʔλຖͷόϦσʔγϣϯͦͷ w ษڧ࣌ؒ w ෼ ࣌ؒ ΑΓେ͖͍஋ w ֶशྔ w

    ߹ܭPSൣғ w ্ݶ  ΑΓେ͖͍஋ w Լݶ  ΑΓখ͍͞஋ ֤ύϥϝʔλຖʹɺೖྗ͞Εͨ஋ΛΤϥʔͱ͢ΔέʔεΛॻ͖ى͜͠
  18. ύϥϝʔλຖͷόϦσʔγϣϯͦͷ ղܾࡁΈͷଞύϥϝʔλͷ஋Λ৚݅ʹΤϥʔͱ͢ΔέʔεΛॻ͖ى͜͠ ᶃ ڭࡐ ᶄ ษڧ࣌ؒˠᶃ͕ೖྗࡁ ᶅ ֶशྔˠᶃᶄ͕ೖྗࡁ w ߹ܭPSൣғ

    ᶆ ϝϞˠᶃᶄᶅ͕ೖྗࡁ ύϥϝʔλఆٛॱʹೖྗ஋Λղܾ ΞΫγϣϯຖʹੜ੒͞ΕΔ *OUFOU)BOEMJOHQSPUPDPMͷ͏ͪ ύϥϝʔλຖͷSFTPMWFϝιου ͕࣮ߦ
  19. ύϥϝʔλຖͷόϦσʔγϣϯͦͷ ղܾࡁΈͷଞύϥϝʔλͷ஋Λ৚݅ʹΤϥʔͱ͢ΔέʔεΛॻ͖ى͜͠ ษڧه࿥ͱͯ͠ड͚෇͚Δσʔλͱͯ͠੒ཱ͠ͳ͍έʔε w ษڧ࣌ؒ w ڭࡐͳ͔ͭ͠ษڧ࣌ؒͳ͠ w ֶशྔ w

    ߹ܭPSൣғ w ൣғͷ৔߹ɺ։͕࢝ऴྃΑΓେ͖͍஋ w ൣғͷ৔߹ɺ։࢝·ͨ͸ऴྃͷΈҎ্ͷ஋ w ڭࡐͳ͠Ͱ߹ܭPSൣғ΁Ҏ্ͷ஋Λઃఆ w ษڧ࣌ؒͳֶ͔ͭ͠शྔͳ͠
  20. ύϥϝʔλͷೖྗ஋Ͱ͸൑ఆͰ͖ͳ͍ΤϥʔΛॻ͖ى͜͠ w Πϯλʔωοτͷ઀ଓεςʔλε w ΦϑϥΠϯͰ͋Δ w ΦϯϥΠϯͷঢ়ଶͰΞϓϦΛىಈ࣌ʹվΊͯૹ৴ॲཧΛࢼߦ͢Δ࢓༷ w 4UVEZQMVTΞϓϦͰͷϩάΠϯεςʔλε w

    ະϩάΠϯͰɺษڧه࿥Λ౤ߘ͢ΔઌͷΞΧ΢ϯτ͕ෆ໌ w ڭࡐ w બ୒ͨ͠ڭࡐ͕ݱࡏຊ୨ʹଘࡏ͠ͳ͍ w ࣗ෼ͷຊ୨ʹଘࡏ͢ΔڭࡐͰͳ͍ͱษڧه࿥ΛೖྗͰ͖ͳ͍࢓༷ w ϝϞ w /(ϫʔυΛؚΉ w /(ϫʔυ͸ΧελϚʔαϙʔτͰৗ࣌ௐ੔Ͱ͖ΔͨΊɺ༗ແΛαʔόʔͰ൑ఆ͢Δ࢓༷
  21. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δֶशྔൣғऴྃͷ஋ public func resolveEnd( for intent: PostStudyRecordIntent, with

    completion: @escaping (PostStudyRecordEndResolutionResult) -> Void) { guard let end = intent.end, Int(truncating: end) > 0 else { completion(PostStudyRecordEndResolutionResult.notRequired()) return } guard intent.material != nil else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noMaterial)) return } guard let start = intent.start, Int(truncating: start) > 0 else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noStart)) return } /* lessThanStartValue, failureLackParameterͷέʔεΛলུ */ completion(PostStudyRecordEndResolutionResult.success(with: Int(truncating: end))) }
  22. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δֶशྔൣғऴྃͷ஋ public func resolveEnd( for intent: PostStudyRecordIntent, with

    completion: @escaping (PostStudyRecordEndResolutionResult) -> Void) { guard let end = intent.end, Int(truncating: end) > 0 else { completion(PostStudyRecordEndResolutionResult.notRequired()) return } guard intent.material != nil else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noMaterial)) return } guard let start = intent.start, Int(truncating: start) > 0 else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noStart)) return } /* lessThanStartValue, failureLackParameterͷέʔεΛলུ */ completion(PostStudyRecordEndResolutionResult.success(with: Int(truncating: end))) } ֶशྔͷه࿥ʹ͸ڭࡐ͕ඞਢͳͷͰ ڭࡐ͕ͳ͍ࢫΤϥʔΛฦ٫
  23. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δֶशྔൣғऴྃͷ஋ public func resolveEnd( for intent: PostStudyRecordIntent, with

    completion: @escaping (PostStudyRecordEndResolutionResult) -> Void) { guard let end = intent.end, Int(truncating: end) > 0 else { completion(PostStudyRecordEndResolutionResult.notRequired()) return } guard intent.material != nil else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noMaterial)) return } guard let start = intent.start, Int(truncating: start) > 0 else { completion(PostStudyRecordEndResolutionResult.unsupported(forReason: .noStart)) return } /* lessThanStartValue, failureLackParameterͷέʔεΛলུ */ completion(PostStudyRecordEndResolutionResult.success(with: Int(truncating: end))) } ֶशྔͷऴྃʹ͸։࢝ͷઃఆ͕ඞਢͳͷͰ ։͕࢝ઃఆ͞Ε͍ͯͳ͍ࢫΤϥʔΛฦ٫
  24. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δ 1PTU4UVEZ3FDPSE 3FTQPOTF public func handle( ɹɹɹɹintent: PostStudyRecordIntent,

    ɹɹɹɹcompletion: @escaping (PostStudyRecordIntentResponse) -> Void) { guard CurrentUser.isLogin else { completion( PostStudyRecordIntentResponse(code: .failureStatusLogout, userActivity: nil)) return } /* failureOffline, failureNotFoundBookshelfEntryͷέʔεɺͦͷଞ΋Ζ΋ΖͷॲཧΛলུ */ StudyRecordRepository.create(studyRecord: studyRecord, success: { _ in completion(PostStudyRecordIntentResponse(code: .success, userActivity: userActivity)) }, ngWordsDetected: { completion( ɹɹɹɹɹɹɹɹPostStudyRecordIntentResponse(code: .failureNgWordsDetected, userActivity: nil)) } }
  25. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δ 1PTU4UVEZ3FDPSE 3FTQPOTF public func handle( ɹɹɹɹintent: PostStudyRecordIntent,

    ɹɹɹɹcompletion: @escaping (PostStudyRecordIntentResponse) -> Void) { guard CurrentUser.isLogin else { completion( PostStudyRecordIntentResponse(code: .failureStatusLogout, userActivity: nil)) return } /* failureOffline, failureNotFoundBookshelfEntryͷέʔεɺͦͷଞ΋Ζ΋ΖͷॲཧΛলུ */ StudyRecordRepository.create(studyRecord: studyRecord, success: { _ in completion(PostStudyRecordIntentResponse(code: .success, userActivity: userActivity)) }, ngWordsDetected: { completion( ɹɹɹɹɹɹɹɹPostStudyRecordIntentResponse(code: .failureNgWordsDetected, userActivity: nil)) } } ະϩάΠϯͷ৔߹ɺ ϩάΠϯ͔ͯ͠Β࣮ߦͯ͠΄͍͠ࢫΤϥʔΛฦ٫
  26. ΤϥʔΛฦ٫ d*OUFOU)BOEMFSTXJGU ྫɿೖྗ͞Εͨ஋ͰษڧΛه࿥͢Δ 1PTU4UVEZ3FDPSE 3FTQPOTF public func handle( ɹɹɹɹintent: PostStudyRecordIntent,

    ɹɹɹɹcompletion: @escaping (PostStudyRecordIntentResponse) -> Void) { guard CurrentUser.isLogin else { completion( PostStudyRecordIntentResponse(code: .failureStatusLogout, userActivity: nil)) return } /* failureOffline, failureNotFoundBookshelfEntryͷέʔεɺͦͷଞ΋Ζ΋ΖͷॲཧΛলུ */ StudyRecordRepository.create(studyRecord: studyRecord, success: { _ in completion(PostStudyRecordIntentResponse(code: .success, userActivity: userActivity)) }, ngWordsDetected: { completion( ɹɹɹɹɹɹɹɹPostStudyRecordIntentResponse(code: .failureNgWordsDetected, userActivity: nil)) } } ϝϞʹ/(ϫʔυؚ͕·Ε͍ͯͨ৔߹ɺ ෆద੾ͳจࣈྻؚ͕·Ε͓ͯΓ౤ߘʹࣦഊͨ͠ࢫ ΤϥʔΛฦ٫
  27. ΞδΣϯμ w 4UVEZQMVTͰϦϦʔεͨ͠ษڧه࿥Λೖྗ͢Δ4JSJ4IPSUDVUT֓ཁ w 4JSJ4IPSUDVUTͰૢ࡞Λड͚෇͚ΔΞΫγϣϯͷબఆ w ର࿩ͷઃܭ w ΞΫγϣϯຖʹೖྗΛड͚෇͚Δύϥϝʔλઃܭ w

    ೖྗ͞ΕͨύϥϝʔλͷΤϥʔॲཧઃܭʴ࣮૷ྫ w ԡ͓͖͍࣮͑ͯͨ͞૷Λ঺հ w ΞΫγϣϯ׬ྃޙɺΞϓϦʹભҠͯ͠΍Γ͍ͨ͜ͱ͕͋Δ৔߹ͷ࣮૷
  28. ΞΫγϣϯ׬ྃϏϡʔλοϓͰΞϓϦىಈ࣌ͷ࣮૷ d*OUFOU)BOEMFSTXJGU public func handle( intent: PostStudyRecordIntent, completion: @escaping (PostStudyRecordIntentResponse)

    -> Void) { /* Τϥʔॲཧ΍౤ߘॲཧ͸লུ */ let userActivity = NSUserActivity( activityType: “Info.plist>NSUserActivityTypesʹఆٛࡁΈͷ໊લ" ) userActivity.title = "ษڧΛه࿥͢Δ" userActivity.userInfo = ["study_challenge": "ࠓिͷ໨ඪਐḿͷ಺༰"] completion( PostStudyRecordIntentResponse( code: .success, userActivity: userActivity) ) }