$30 off During Our Annual Pro Sale. View Details »

iOSのKeyboard Extensionで日本語入力できるキーボードアプリを作ろう! - iOSDC2023

Keita Miwa
September 03, 2023

iOSのKeyboard Extensionで日本語入力できるキーボードアプリを作ろう! - iOSDC2023

Keita Miwa

September 03, 2023
Tweet

Other Decks in Programming

Transcript

  1. ೔ຊޠೖྗͰ͖Δ


    ΩʔϘʔυΞϓϦΛ࡞Ζ͏ʂ
    iOSDC Japan 2023
    iOSͷKeyboard ExtensionͰ೔ຊޠIME։ൃʹೖ໳

    View Slide

  2. azooKey
    • ೔ຊޠೖྗػೳ


    • ͔ͳ׽ࣈม׵


    • ༧ଌม׵


    • ֆจࣈɾه߸ྨͷೖྗ


    • Ϣʔβࣙॻ


    • ֶश


    • ޡΓగਖ਼


    • ΩʔϘʔυΞϓϦػೳ


    • ணͤସ͑


    • ϥΠϒม׵


    • ΧελϜΩʔ


    • ΧελϜλϒ


    • ίϐʔཤྺอଘ


    • छʑͷઃఆ
    https://github.com/ensan-hcl/azooKey
    OSSʂ

    View Slide

  3. ࿩͢͜ͱ
    • ΩʔϘʔυΞϓϦͷ֓ཁ


    • ೔ຊޠೖྗ


    • ࢓૊Έ


    • ࡞ͬͯΈΑ͏


    • ύοέʔδͷ঺հ


    • ࣙॻ


    • ΩʔϘʔυͷUIʢͷਏ͍ͱ͜Ζʣ


    • ·ͱΊ

    View Slide

  4. ΩʔϘʔυΞϓϦ

    View Slide

  5. ΩʔϘʔυΞϓϦ
    = Keyboard Extension
    • ඪ४ΩʔϘʔυͱಉ༷ʹར༻Ͱ͖Δ


    • γεςϜͷ΄ͱΜͲͲ͜Ͱ΋ಈ͘


    • ػೳ໘͸੍໿ڧΊ


    • ϓϥΠόγʔ


    • Ϧιʔε


    • ίϯςφΞϓϦʹಉࠝͯ͠഑෍͢Δ


    • ೔ຊޠೖྗରԠͷΞϓϦ͸গͳ͍

    View Slide

  6. ೔ຊޠೖྗΞϓϦ
    • ίϯςφΞϓϦΛ࡞ΔʢઃఆɾνϡʔτϦΞϧʣ


    • ΩʔϘʔυͷΠϯλʔϑΣʔεΛ࡞Δ


    • ೔ຊޠೖྗΤϯδϯΛ࡞Δʢ͕͜͜ຊؙʣ


    • ม׵ΤϯδϯΛ࣮૷͢Δ


    • ࣙॻ΋࡞Δ

    View Slide

  7. ೔ຊޠೖྗ

    View Slide

  8. ೔ຊޠೖྗ͍Ζ͍Ζ
    • ͍ΘΏΔʮ͔ͳ׽ࣈม׵ʯʢͻΒ͕ͳΛͨ͘͞Μଧͬͯม׵͢Δ΍ͭʣ


    • ଟ͘ͷ؀ڥͰσϑΥϧτͷ೔ຊޠೖྗํ๏


    • ࠓճ͸͜ΕΛओʹѻ͍·͢


    • SKKʢSimple Kana to Kanji conversion programʣ


    • iOSʹ΋FlickSKKɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ͕͋Γ·͢


    • ׽ࣈ௚઀ೖྗ


    • ׽ࣈΛ௚઀ೖྗ͢Δํࣜɺෳࡶͳม׵ΤϯδϯཁΒͣ
    https://github.com/codefirst/FlickSKK

    View Slide

  9. ๲େͳީิ
    • Ұͭͷೖྗʹରͯ͠ɺ
    ͨ͘͞Μͷީิ͕ߟ͑
    ΒΕΔ


    • ؒʹ߹͍ͦ͏Ͱ͢


    • ਅʹѪ૝࿹૥


    • ϚχΞҠૹDeath
    ೖྗɿ·ʹ͍͋ͦ͏Ͱ͢

    Ҡૹ
    ؒʹ߹͍ ͦ͏ Ͱ͢
    ډ
    ʹ

    ձ͍
    ү
    Ѫ૝
    ૯ग़

    ϚχΞ %FBUI

    View Slide

  10. ๲େͳީิ
    • Ұͭͷೖྗʹରͯ͠ɺ
    ͨ͘͞Μͷީิ͕ߟ͑
    ΒΕΔ


    • ؒʹ߹͍ͦ͏Ͱ͢


    • ਅʹѪ૝࿹૥


    • ϚχΞҠૹDeath
    ೖྗɿ·ʹ͍͋ͦ͏Ͱ͢

    Ҡૹ
    ؒʹ߹͍ ͦ͏ Ͱ͢
    ډ
    ʹ

    ձ͍
    ү
    Ѫ૝
    ૯ग़

    ϚχΞ %FBUI

    View Slide

  11. ๲େͳީิ
    • Ұͭͷೖྗʹରͯ͠ɺ
    ͨ͘͞Μͷީิ͕ߟ͑
    ΒΕΔ


    • ؒʹ߹͍ͦ͏Ͱ͢


    • ਅʹѪ૝࿹૥


    • ϚχΞҠૹDeath
    ೖྗɿ·ʹ͍͋ͦ͏Ͱ͢

    Ҡૹ
    ؒʹ߹͍ ͦ͏ Ͱ͢
    ډ
    ʹ

    ձ͍
    ү
    Ѫ૝
    ૯ग़

    ϚχΞ %FBUI

    View Slide

  12. ͔ͳ׽ࣈม׵
    • ม׵ΞϧΰϦζϜ


    • ୯ޠͷ1-gramͱ඼ࢺͷ2-gramΛ࢖͏
    ≒ʮ୯ޠ1ͭ͋ͨΓͷείΞ + 2ͭฒΜͩ඼ࢺͷϖΞͷείΞʯΛ࠷େԽ


    • ࣙॻσʔλ


    • ܗଶૉղੳ༻ࣙॻΛϕʔεʹࣗ࡞͠·͢

    View Slide

  13. είΞͷߟ͑ํ
    • ͔ͳྻʹର͢ΔՄೳͳ׽ࣈม׵ީิ͕େྔʹ͋Δ


    • ͨ͘͞Μͷ݁ՌΛධՁͯ͠ɺॱҐ෇͚͍ͨ͠


    →֤݁ՌͷʮείΞʯΛܭࢉ


    • සൟʹग़ͯ͘Δ୯ޠͷ༏ઌॱҐΛ্͍͛ͨ
    →୯ޠͷग़ݱ֬཰͕ߴ͍ީิʹྑ͍είΞΛ༩͑Δ


    • จ๏΋গ͠ߟྀ͍ͨ͠
    →2ͭฒΜͩ඼ࢺͷϖΞͷग़ݱ֬཰͕ߴ͍ީิʹ
    ྑ͍είΞΛ༩͑Δ

    View Slide

  14. ୯ޠͷείΞʢؾ࣋ͪʣ
    ࢥ͏
    ͓ໟ
    ૝͏
    Ա͏
    ʮࢥ͏ʯͷස౓͕ߴ͍ͷͰɺʮ͓΋͏ʯͷม׵Ͱ͸ʮࢥ͏ʯΛ༏ઌ

    View Slide

  15. ඼ࢺͷϖΞͷείΞʢؾ࣋ͪʣ
    ݴ༿Λ
    ॿࢺϮ
    ࿩͢
    ಈࢺ
    ͸՘ࢠ
    ॿࢺϋʴ໊ࢺ
    ʮॿࢺϮʯͷ͋ͱʹʮॿࢺϋʯ͸དྷʹ͍͘ͷͰ͜ͷม׵Ͱ͸ʮ࿩͢ʯΛ༏ઌ

    View Slide

  16. ࣮ࡍͷܭࢉ

    Ҡૹ
    ؒʹ߹͍ ͦ͏ Ͱ͢
    ډ
    ʹ

    ձ͍
    ү
    Ѫ૝
    ૯ग़

    ϚχΞ %FBUI

    • ީิ͸ͨ͘͞Μ͋Δ


    • είΞ͕࠷େʹͳΔ
    Α͏ͳީิΛ୳ࡧ


    • ݟ͚ͭΒΕΔͳΒํ๏
    ͸ͳΜͰ΋͍͍
    ೖྗɿ·ʹ͍͋ͦ͏Ͱ͢

    View Slide

  17. ࣮ࡍͷܭࢉ
    • ޮ཰Α͘ܭࢉ͢ΔͨΊ
    ʮViterbiΞϧΰϦζϜʯ
    ͕࢖͑Δɻ


    • ಈతܭը๏ͷҰछ
    ೖྗɿ·ʹ͍͋ͦ͏Ͱ͢

    Ҡૹ
    ؒʹ߹͍ ͦ͏ Ͱ͢
    ډ
    ʹ

    ձ͍
    ү
    Ѫ૝
    ૯ग़

    ϚχΞ %FBUI

    View Slide

  18. ࡞ͬͯΈΑ͏

    View Slide

  19. ϑϧ࣮૷ʢ170ߦʣ
    https://github.com/ensan-hcl/KanaKanjiConversionSamples
    ensan-hcl/KanaKanjiConversionSamples

    View Slide

  20. ࣮૷ʢWordʣ

    View Slide

  21. ࣮૷ʢNodeʣ

    View Slide

  22. ࣙॻʢఆٛͷΈʣ

    View Slide

  23. ม׵ثʢఆٛͷΈʣ

    View Slide

  24. ม׵ث①

    View Slide

  25. ม׵ث②

    View Slide

  26. ม׵ث③

    View Slide

  27. ม׵ث④

    View Slide

  28. ׬੒ʂ

    View Slide

  29. ࣮༻͢Δʹ͸ʁ
    • ෳ਺ͷީิʢN-BestղʣΛఏҊͰ͖ΔΑ͏ʹ͢Δ


    • จઅ෼ׂɺ෦෼ม׵ɺ༧ଌม׵ͳͲΛαϙʔτ͢Δ


    • ม׵ͷߴ଎Խ


    • ΩϟογϡΛར༻ͯ͠෦෼తͳมߋʹରͯ͠ߴ଎ͳॲཧΛߦ͏


    • ଥ౰Ͱ͸ͳ͍ީิΛͳΔ΂͘ૣ͘ʹࣺͯΔ


    • ࣙॻҾ͖ͷߴ଎ԽɾলϝϞϦԽ


    • LOUDS Trieͱ͍͏σʔλߏ଄͕໾ཱͭʢଞʹ΋͍ΖΜͳѹॖख๏͕͋Δʣ

    View Slide

  30. AzooKeyKanaKanjiConverter
    • ࣮૷ࡁΈͷ͔ͳ׽ࣈม׵ύοέʔδ


    • https://github.com/ensan-hcl/
    AzooKeyKanaKanjiConverter


    • SwiftPMͰϓϩδΣΫτʹ௥ՃͰ͖·͢


    • ࣙॻʢ഑෍͋ΓʣΛೖΕΕ͹਺ߦͷ
    ίʔυͰ͔ͳ׽ࣈม׵Ͱ͖·͢

    View Slide

  31. ࣙॻ

    View Slide

  32. ࣙॻʹඞཁͳ΋ͷ
    • ͜Μͳײ͡ͷσʔλ͕ཉ͍͠


    • ୯ޠͷಡΈɿΘ͍͕ͤͩͩ͘


    • ୯ޠͷදهɿૣҴాେֶ


    • ୯ޠͷ඼ࢺɿݻ༗໊ࢺ


    • ୯ޠͷείΞɿ10


    • ඼ࢺͷϖΞͷείΞ

    View Slide

  33. ࣙॻʹඞཁͳ΋ͷ
    • ͜Μͳײ͡Ͱ४උͰ͖Δ


    • ୯ޠͷಡΈ→ܗଶૉղੳ༻ͷࣙॻ͔ΒऔΔ


    • ୯ޠͷදه→ܗଶૉղੳ༻ͷࣙॻ͔ΒऔΔ


    • ୯ޠͷ඼ࢺ→ܗଶૉղੳ༻ͷࣙॻ͔ΒऔΔ


    • ୯ޠͷείΞ→Θ͔Βͳ͍


    • ඼ࢺͷϖΞͷείΞ→Θ͔Βͳ͍

    View Slide

  34. ࣙॻʹඞཁͳ΋ͷɿස౓ͷ৘ใ
    • είΞͷܭࢉ


    • ࣮ࡍͷݴޠσʔλΛܗଶૉղੳ


    • ස౓ͷ৘ใΛ༻͍ͯείΞΛܾఆ


    • ࣙॻΛੜ੒͢Δ

    View Slide

  35. ࣙॻͷվળɿ௥ՃͰ΍Δ͜ͱ
    • ෳ߹ޠͷੜ੒ɿස౓ͷߴ͍ෳ߹ޠΛҰޠͱͯࣙ͠ॻొ࿥͢Δ


    • ܗଶૉղੳ༻ࣙॻͷੜ੒ɿΑΓਫ਼౓ͷߴ͍ղੳΛߦ͏ͨΊɺܗଶૉղੳ༻ࣙ
    ॻΛࣗલͰੜ੒


    • ਓ໊ࣙॻͷੜ੒ɿ࠷৽ͷਓ໊Λαϙʔτ͢ΔͨΊɺ༗໊ਓͷσʔλΛ࡞Δ


    • ಉදهҟಡޠͷௐ੔ɿʮ೔ຊʢχοϙϯɾχϗϯʣʯͷΑ͏ͳಉදهҟಡޠ
    ͷείΞௐ੔Λߦ͏


    • ௥Ճޠኮɿه߸ͳͲɺࣙॻ΁ͷ௥ՃޠኮΛखಈͰ४උ

    View Slide

  36. ࣙॻσʔλͷ഑෍
    • azooKeyͷࣙॻσʔλΛ഑෍͍ͯ͠·͢


    • ϏϧυࡁΈόΠφϦ


    • ੜCSVσʔλ


    • azooKeyͷREADMEʹϦϯΫ͕͋Γ·͢


    • Apache License Version 2.0Ͱ͢

    View Slide

  37. ΩʔϘʔυͷUIʢͷਏ͍ͱ͜ʣ

    View Slide

  38. ೖྗঢ়ଶ؅ཧ
    • Ϣʔβ͸ΩʔϘʔυΛܦ༝ͤͣʹςΩετΛૢ࡞Ͱ͖Δ


    • ςΩετͷબ୒


    • ΧʔιϧҠಈ


    • ϖʔετ


    • ͜ΕΒΛద੾ʹݕ஌ͯ͠ॲཧ͠ͳ͍ͱɺϢʔβʹݟ͍͑ͯΔը໘ͱ
    ΩʔϘʔυͷ಺෦ঢ়ଶ͕ζϨͯ͠·͏


    • ΩʔϘʔυΛܦ༝͠ͳ͍ૢ࡞ʹରԠͨ͠ೖྗঢ়ଶͷ؅ཧ͕ඞཁ

    View Slide

  39. ೖྗঢ়ଶ؅ཧɿಓ۩
    • Keyboard Extension͕औΕΔͷ͸
    ҎԼͷ3ͭͷΈ


    • Χʔιϧલͷจࣈྻ:
    var documentContextBeforeInput: String?


    • બ୒͍ͯ͠Δจࣈྻ:
    var selectedText: String?


    • Χʔιϧޙͷจࣈྻ:
    var documentContextAfterInput: String?


    • Keyboard Extension͕Ͱ͖Δͷ͸
    ҎԼͷ3ͭͷΈʢ˞ʣ


    • ΧʔιϧҐஔ΁ͷจࣈͷૠೖ:
    func insertText(String)


    • Χʔιϧલͷจࣈͷ࡟আ:
    func deleteBackward()


    • ΧʔιϧͷҠಈ:
    func adjustTextPosition(byCharacterOffset: Int)
    • Keyboard Extension͕ड͚औΕΔ௨஌͸ҎԼͷ2ͭͷΈ


    • Ϣʔβ͕ʮԿ͔͢Δʯલ: func textWillChange(UITextInput?)


    • Ϣʔβ͕ʮԿ͔ͨ͠ʯޙ: func textDidChange(UITextInput?)
    ʢ˞ʣਖ਼֬ʹ͸΋͏গ͋͠Γ·͕͢ɺೖྗ؅ཧʹ࢖͑Δ΋ͷ͸͜Ε͚ͩͰ͢

    View Slide

  40. ೖྗঢ়ଶ؅ཧɿϢʔβʹΑΔΧʔιϧҠಈͷݕग़ྫ
    1. Ϣʔβ͕ʮԿ͔͢Δʯ௨஌Λड͚औΔ


    2. ͜ͷλΠϛϯάͰʮΧʔιϧͷલޙʯͷςΩετΛอଘ(before)


    3. Ϣʔβ͕ʮԿ͔ͨ͠ʯ௨஌Λड͚औΔ


    4. ͜ͷλΠϛϯάͰʮΧʔιϧͷલޙʯͷςΩετΛอଘ(after)


    5. beforeͷࠨӈΛ࿈݁ͨ͠΋ͷͱɺafterͷࠨӈΛ࿈݁ͨ͠΋ͷ͕ಉ͔֬͡ೝ
    →ಉ͡ͳΒɺςΩετΛมԽͤ͞Δૢ࡞Ͱ͸ͳ͘ɺΧʔιϧҠಈͱ෼͔Δ
    →beforeͱafterͷࠨͷจࣈ਺Λൺֱ͠ɺ͕ࠩҠಈͨ͠จࣈ਺ͱ෼͔Δ


    ˞࣮ࡍʹ͸ʮϖʔετʯʮΧοτʯͳͲෳ਺ͷૢ࡞ͷՄೳੑΛಉ࣌ʹௐ΂Δ

    View Slide

  41. APIͷ೉͍͠ಈ࡞①
    • υΩϡϝϯτʹॻ͔Ε͍ͯͳ͍ڍಈ͕ଟ͍


    • ΧʔιϧͷҠಈ: func adjustTextPosition(byCharacterOffset: Int)


    • υΩϡϝϯτʹΑΔͱҾ਺͸Ҡಈ͢Δจࣈ਺


    • ࣮ࡍ͸จࣈ਺Ͱ͸ͳ͘UTF-16ίʔυϙΠϯτ਺


    • ᷖᮣʹ࣮૷͢ΔͱֆจࣈͷؒʹΧʔιϧ͕ೖͬͨΓ͢Δ


    • Ҡಈ͢ΔલʹΧʔιϧલޙΛ֬ೝ͠ɺίʔυϙΠϯτΛ਺͑Δඞཁ͕͋Δ

    View Slide

  42. APIͷ೉͍͠ಈ࡞②
    • ೖྗதͷจࣈྻʹ৭͚ͭΔ΍ͭ: func setMarkedText(String?, selectedRange: NSRange)


    • ৭͸͔֬ʹ͕ͭ͘ɺϢʔβૢ࡞͕Ұ੾τϥοΫग़དྷͳ͘ͳΔ


    • બ୒͍ͯ͠Δจࣈྻ: var selectedText: String?


    • υΩϡϝϯτʹΑΔͱબ୒͍ͯ͠Δจࣈྻ


    • ࣮ࡍ͸ʮબ୒͍ͯ͠Δจࣈྻɻͨͩ͠3ߦҎ্ͷจͷ৔߹͸࠷ॳͱ࠷ޙͷ
    1ߦΛ͚ͬͭͨ͘΍ͭʯͱ͍͏ڍಈ


    • ࢓༷ʢςΩετϑΟʔϧυଆͷ࣮૷ʹΑΔʣ

    View Slide

  43. ϝϞϦ੍ݶ
    • ΩʔϘʔυΞϓϦʹڐ͞ΕͨϝϞϦ͸60MBલޙʢOSɾσόΠεґଘʣ


    • ্ݶ෇ۙͰ͸ಈ࡞͕ۃ୺ʹ஗͘ͳΔͷͰɺ࣮࣭తʹ͔ͦ͜Β10~20MBఔ౓ݮΔ


    • ϝϞϦΛফඅ͢ΔཁҼ


    • ࣙॻσʔλ


    • ணͤସ͑ͷը૾


    • ֆจࣈϑΥϯτͷΩϟογϡ


    • Ұ౓දࣔ͞Εͨֆจࣈ͸ϝϞϦʹϑΥϯτͷΩϟογϡΛ࢒͢ʢ࡟আෆೳʣ


    • ֆจࣈશͯͰ10MBҎ্͍͔࣋ͬͯΕΔ→ֆจࣈΩʔϘʔυͰམͪΔʂ

    View Slide

  44. UIͷָ͍͠ͱ͜Ζ
    • ޻෉ͷ༨஍͕ଟ͍


    • ৭ʑͳ഑ྻɺศརͳΩʔɺ৽͍͠UIͳͲ


    • δΣενϟͳͲ΋޻෉Ͱ͖Δ


    • ΩʔϘʔυͷUIͷՄೳੑΛ୳ΕΔ


    • ΩʔϘʔυ͸ಛҟͳΞϓϦέʔγϣϯ


    • ΩʔϘʔυ্Ͱʓʓग़དྷͨΒศརͰ͸ʂΛ
    ࣮ݱͰ͖Δ

    View Slide

  45. ·ͱΊ

    View Slide

  46. 🔥೔ຊޠೖྗ͸Ͱ͖Δʂ


    🔥ΩʔϘʔυΞϓϦ΋Ͱ͖Δʂ


    🔥೔ຊޠೖྗΞϓϦΛ࡞Ζ͏ʂ


    ✅ ม׵Τϯδϯɿ͋Δ


    ✅ ࣮૷αϯϓϧɿ͋Δ


    ✅ ΦϦδφϧͷ೔ຊޠೖྗΞϓϦɺม׵Τϯδϯɺ഑ྻɺUIɺ࡞Γ·͠ΐ͏ʂ
    ೔ຊޠೖྗΞϓϦΛ࡞Ζ͏ʂ
    Your Own Keyboard🔥🔥

    View Slide

  47. ϑΟʔυόοΫ͓଴ͪͯ͠·͢

    View Slide

  48. ͓͢͢Ίͷࢿྉ
    • Creating a custom keyboard | Apple Developer Documentation, https://developer.apple.com/
    documentation/uikit/keyboards_and_input/creating_a_custom_keyboard/


    • ޻౻୓, খদ߂޾, ՖԬढ़ߦ, ޲Ҫ३, & ాാ༔հ. (2011). ౷ܭత͔ͳ׽ࣈม׵γεςϜ Mozc. ݴ
    ޠॲཧֶձୈ 17 ճ೥࣍େձൃද࿦จू, 948-951.,
    https://anlp.jp/proceedings/annual_meeting/2011/pdf_dir/C4-3.pdf


    • iOSΧελϜΩʔϘʔυͷ࡞Γํ - Qiita,
    https://qiita.com/Kyome/items/4257de4e33d3647085e6


    • ಙӬ୓೭. (2012).೔ຊޠೖྗΛࢧ͑Δٕज़ʕมΘΓଓ͚Δίϯϐϡʔλͱݴ༿ͷੈք, ٕ
    ज़ධ࿦ࣾ,
    https://gihyo.jp/book/2012/978-4-7741-4993-6


    • KeyboardKit/KeyboardKit - GitHub, https://github.com/KeyboardKit/KeyboardKit

    View Slide