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

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

対話を頑張らなくても作れる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) ) }