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

iOSエンジニアがKMPで大規模アプリの ロジック共通化をしてうまくできている話 / iOSDC2021

A65c56fbce87057b9ee064122601d7b5?s=47 Kenzo Nirasawa
September 18, 2021

iOSエンジニアがKMPで大規模アプリの ロジック共通化をしてうまくできている話 / iOSDC2021

A65c56fbce87057b9ee064122601d7b5?s=128

Kenzo Nirasawa

September 18, 2021
Tweet

Transcript

  1. iOSエンジニアがKMPで大規模アプリの
 ロジック共通化をしてうまくできている話
 (株)リクルート 韮澤 賢三
 浅井 徹 
 1

  2. はじめに
 2

  3. 自己紹介
 韮澤 賢三(@nirazo)
 株式会社リクルート 
 iOSエンジニア歴約7年
 ホットペッパーグルメアプリ開発チームリーダー兼アプリリプレイ スプロジェクトリーダー
 略歴
 2012年4月

    Webサービス企業に新卒入社 
 2015年11月 リクルートライフスタイル中途入社 
 2019年10月 ホットペッパーグルメ開発チーム参画 
 3
  4. 浅井 徹(@trsxxii)
 株式会社リクルート 
 iOSエンジニア歴 6~7年
 ホットペッパーグルメアプリ KMP開発チームリーダー 
 略歴


    2014年4月 Webサービス企業に新卒入社 
 2019年11月 リクルートライフスタイルに中途入社 
 自己紹介
 4 浅井さんの写真だよ
  5. 本発表のゴール
 5 Kotlin Multiplatformに興味はあるけど踏み切れない、そんな方の不安を解消し、 iOSエンジニアでもやれるんだという気持ちになってもらう
 


  6. • ホットペッパーグルメについて
 • Kotlin Multiplatform Projectとは
 • ホットペッパーグルメとKMP
 • 我々の不安要素は実際どうだったのか

    
 ◦ ロジック共通化はうまくできるのか? 
 ◦ ObjCヘッダーでIFが使いづらいのでは? 
 ◦ DBやUserDefaults、Keychainにアクセスできるのか? 
 ◦ iOSの知識に追加でどんな知識が必要か? 
 • まとめ
 アジェンダ
 
 6
  7. リクルートは多数のサービスを運営しています
 7
  メディア&ソリューションSBU 
 HRテクノロジーSBU
 人材派遣SBU
 販促領域
 人材領域
 国内派遣
 海外派遣


    etc...
 選択・意思決定を支援する情報サービスを提供し、
 「まだ、ここにない、出会い。より速く、シンプルに、もっと近くに」を実現する
  8. ホットペッパーグルメを開発しています
 
 
 8

  9. Kotlin Multiplatform Projectとは
 9

  10. KMPとは - 概要
 • Kotlin Multiplatform Project(以後KMP)とは、Kotlinで記述されたコードを 
 異なるプラットフォーム用にコンパイルできるプロジェクトのこと 


    10 引用元:https://kotlinlang.org/docs/multiplatform.html 

  11. KMPとは - KMM
 • その中でも、KMPの一つのユースケースである、 iOS/Androidのコード共有を実現することを 
 Kotlin Multiplatform Mobile(KMM)と言う

    
 ◦ 今回説明することは厳密にはKMMに関する内容
 
 • FlutterやReactNativeなどとは違い、 
 ビジネスロジック部分のみを共通化する 
 • あくまでもViewは各プラットフォームで実装する 
 11 引用元:https://kotlinlang.org/lp/mobile/ 

  12. KMPとは - プラットフォーム固有API
 12 • 共通コードはcommonMain、共通化できないようなプラットフォーム固有のコードは、 iosMain/androidMainというフォルダに定義できる ※
 • expectというinterfaceのようなコードをcommonMainに記述し、

    
 actualを使って各プラットフォーム固有のiosMain/androidMainに実際の処理を記述する 
 ※実際にはbuild.gradle.ktsで設定したフォルダ名となるがcommonMain/iosMain/androidMainが一般的 
 androidMain
 iosMain
 引用元:https://kotlinlang.org/docs/multiplatform.html 

  13. KMPとは - iOS開発
 • 共通コードはKotlin/JVMでAndroid/Java Archiveに、 
 Kotlin/NativeでApple Frameworkにビルドされる 


    • KMPでは、Apple Frameworkを作成するGradle Taskが準備されており、 
 これをXcodeのBuild Phasesで設定をすることでiOSアプリの開発が出来るようになる 
 13 Android/Java Archive (.aar / .jar) shared code Apple Framework (.framework) Kotlin/JVM
 Kotlin/Native
 引用元:https://kotlinlang.org/docs/mobile/integrate-in-existing-app.html 

  14. • 前述したApple Frameworkで生成されるバイナリのヘッダーはObjective-Cヘッダーになっている 
 ◦ iOS開発ではObjective-Cヘッダーを通して、Swiftから使用することとなる 
 • できるだけSwiftらしいInterfaceになるように多くのAttributeが指定されている 


    KMPとは - iOS開発
 14 Swiftから使うための命名
 Nullable/NonNull指定

  15. ホットペッパーグルメとKMP
 15

  16. ホットペッパーグルメとKMP
 • ホットペッパーグルメアプリはリリースから10年以上が経過し、開発を継続していくに 
 あたっての課題が浮き彫りになってきた 
 ◦ 10年以上が経過した今も大規模な設計変更等は無く、リリース当初の実装に継ぎ足し開発を 
 行ってきた


    16 ソースコードの 肥大化 ソースコードの 複雑化 開発スピードの鈍化 障害防止の 難度上昇
  17. ホットペッパーグルメとKMP
 • 今後の安定した開発のため、コードリニューアル・リアーキテクチャを決断し、 
 クロスプラットフォーム技術の検討を実施 
 ◦ 開発工数の削減
 ◦ 予期せぬOS間差分を防ぐことによる品質の安定化

    
 
 • クロスプラットフォームの中でもKotlin Multiplatformを採用 
 ◦ UIは各プラットフォームに準拠させたい 
 ◦ Kotlinで書けるためキャッチアップの難易度はそこまで高くないと判断 
 17
  18. ホットペッパーグルメとKMP
 • iOS / Android / Shared (KMP担当)の3チーム構成でプロジェクト進行中 
 ◦

    iOS/Androidはそれぞれ最大8名、Sharedは最大4名 
 18 Android iOS Shared フェーズによってSharedからiOS, Androidへ移籍

  19. KMP採用にあたって、我々も不安がたくさんあった
 19 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は

    できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?

  20. 我々の不安要素は実際どうだったのか
 20

  21. KMP採用にあたって、我々も不安がたくさんあった
 21 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は

    できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?

  22. ロジック共通化は結局うまくできるのか?
 • ホットペッパーグルメのアーキテクチャは以下のようになっている 
 ◦ KMPを使用したロジックの共通化部分は赤枠部分 
 22

  23. ロジック共通化は結局うまくできるのか?
 23 細かい変更はあるもののアーキテクチャ図通りに実装ができており、ロジック共通化もうまくいっ ている。

  24. ロジック共通化は結局うまくできるのか?
 • KMP対象のビジネスロジック部分のコード行数比率を見ると、ほぼすべてのコードを 
 共通化することに成功している
 • commonMainの中にはOSによるif文が存在しているが、それもかなり少ない 
 24 対象


    コード行数比率
 commonMain
 99.13%
 androidMain
 0.45%
 iosMain
 0.42%

  25. ロジック共通化は結局うまくできるのか?
 25 • 最も差分が出やすいライブラリ使用部分の一部を共通化しない選択をしている 
 • 同じ機能の3rd Partyライブラリを使う場合に、共通部分にinterfaceを持たせて、 
 各アプリコードに実装する判断をした

    
 ◦ 共通化できないものを無理に共通コードには入れない方針 
 ◦ interface提供しているライブラリの数も7種類と少ない 
 ※ネットワークや永続化領域へのアクセスなど主要なものは公式ライブラリを使用している 
 commonMain
 Android専用
 ライブラリ
 iOSアプリ
 Androidアプリ
 iOS専用
 ライブラリ
 interface
 共通コード
 interface提供するライブラリの種類 
 数
 ログ系ライブラリ
 3種類
 社内ライブラリ
 1種類
 3rd Partyライブラリ
 3種類

  26. ロジック共通化は結局うまくできるのか?
 26 細かい変更はあるもののアーキテクチャ図通りに実装ができており、ロジック共通化もうまくいっ ている。

  27. KMP採用にあたって、我々も不安がたくさんあった
 27 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は

    できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?

  28. ObjCヘッダーでIFが使いづらい?
 KMP側の実装やiOS側の実装の工夫により、膨大な工数やアーキテクチャ変更無く回避可能 
 28 使いづらい部分はあるものの、そもそも機能が動かない・アーキテクチャが崩壊するといったレベ ルの問題は発生していない

  29. ObjCヘッダーでIFが使いづらい?
 大きな問題は発生していないものの、そもそもKotlin <-> Obj-Cの変換時の制約のために、 
 シンプルな実装にできない箇所が存在する 
 • Generics定義が再帰的になる場合、iOSから見るとAnyになってしまう 


    • 無限アンダースコア問題
 • Kotlinのinterface内にメソッドをデフォルト実装するとiOSでは実装を求められてしまう 
 • inline classを解釈できない
 • クラスが階層的に表現できない問題 
 • Enum問題
 29
  30. ObjCヘッダーでIFが使いづらい?
 大きな問題は発生していないものの、そもそもKotlin <-> Obj-Cの変換時の制約のために、 
 シンプルな実装にできない箇所が存在する 
 • Generics定義が再帰的になる場合、iOSから見るとAnyになってしまう 


    • 無限アンダースコア問題
 • Kotlinのinterface内にメソッドをデフォルト実装するとiOSでは実装を求められてしまう 
 • inline classを解釈できない
 • クラスが階層的に表現できない問題 
 • Enum問題
 30
  31. • Kotlin側でGenericsが階層構造になっている場合、iOSから見るとAny(id型)になってしまう 
 Generics階層構造でAny問題
 31 Generics
 Generics in Generics 


  32. Generics階層構造でAny問題(解決策)
 • Results<T, S>のTに入る型をジェネリクスを含むクラスをやめて、ジェネリクスを含まない型に変更 することで回避した
 32 Genericsをラップするclassを作成して Resultsに入れる


  33. Generics再帰でAny問題
 • Issueが上がっているが対応バージョンは未定 
 ◦ https://youtrack.jetbrains.com/issue/KT-41847 
 33

  34. 無限アンダースコア問題
 • 同名・同引数名のメソッドが複数ある場合、Swiftコードでは引数にアンダースコアが入ったメソッド になる
 34 引数名にアンダースコアが入ってしまう 
 同名・同引数名のメソッド 


  35. 無限アンダースコア問題
 • KMPではKotlin <-> Obj-C変換にあたり、コンパイル時の名前空間被りを引数名に 
 アンダースコアをつけることで解消している 
 ◦ Issueは上がっているが対応バージョンは未定

    
 ▪ https://youtrack.jetbrains.com/issue/KT-43087 
 • 我々のコードでは全UseCaseがexecute(input: Input)という統一の名前のメソッドを 
 持つという規約があったため、この影響を受けてしまった 
 
 35
  36. 無限アンダースコア問題(解決策)
 • 引数名をinputからUseCaseに応じたInput名に変更することで名前被りを防いだ 
 
 
 36 UseCase毎にinputの引数名を変 更


  37. ObjCヘッダーでIFが使いづらい?
 KMP側の実装やiOS側の実装の工夫により、膨大な工数やアーキテクチャ変更無く回避可能 
 37 使いづらい部分はあるものの、そもそも機能が動かない・アーキテクチャが崩壊するといったレベ ルの問題は発生していない

  38. KMP採用にあたって、我々も不安がたくさんあった
 38 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は

    できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?

  39. DBやUserDefaults、Keychain、SharedPreferenceにアクセスできる?
 39 DB、その他ローカルデータ※ 保存領域への値保存・取得は可能 
 完全な共通化はできないが、設計次第でほぼ共通化することが可能 
 保存領域 使えるライブラリ DBアクセス

    • SQLDelight • Realm ローカルデータアクセス • multiplatform-settings ※ UserDefaults, Keychain, SharedPreferenceを便宜上まとめてローカルデータと呼ぶ

  40. DBへのアクセス
 • SQLDelightというライブラリを使い、SQLiteをKMPで利用可能 
 • RealmもKMPで利用できるライブラリを開発中だが、未だα版でありSQLDelightほど 
 市民権を得ていない
 ◦ スター数はSQLDelight:

    約4100, Realm: 約300 (8/23現在) 
 • ホットペッパーグルメではSQLDelightを採用した 
 40
  41. SQLDelightの使い方と共通化可否
 • DBのインスタンス生成コード(各OS1行程度)以外の処理は全て共通化が可能! 
 41 やること概要 やること詳細 共通化可否 スキーマ定義・SQL文定義 スキーマ定義ファイルに

    SQL文を記述 可 DBのインスタンス作成 OS毎に初期化処理を実装 不可 DB操作用コード実装 自動生成されたメソッド経由で DB操作処理を 実装 可
  42. SQLDelightの使い方
 • DBのインスタンス作成をOS毎に実装 
 ◦ プラットフォーム毎にDriverが用意されているため、ここは共通化不可 
 42 expectでdb生成メソッド定義
 androidMain


    iosMain

  43. SQLDelightの使い方
 • sqファイルから自動生成されたメソッドを使ってアプリからDBを操作するコードを書く 
 43 “テーブル名”Queries経由で、sq ファイルに定義したメソッドを呼 び出せる


  44. ローカルデータアクセスの共通化可否
 44 • multiplatform-settingsというライブラリでアクセス可能 
 • 暗号化無しの場合はコードを完全に共通化可能 
 • 暗号化有りの場合もオブジェクトのインスタンス生成コード(数行程度)以外の処理は全て共通化が

    可能
 やること概要 共通化可否 UserDefaults, SharedPreference オブジェクトのインスタンス生成 可 オブジェクトへのRead, Write処理 可 Keychain, 暗号化有り SharedPreference オブジェクトのインスタンス生成 不可 オブジェクトへのRead, Write処理 可
  45. UserDefaults、SharedPreference(暗号化無し)
 • シンプルにSettingsインスタンスを生成し、put, getするのみ 
 ◦ 共通化も可能
 45 Settingsのインスタンスを作成 


    シンプルにget, put

  46. Keychain、SharedPreference(暗号化有り)
 • expect classとしてSettings型のプロパティを持つクラスを定義し、OS毎に初期化処理を実装 
 46 expectSettings変数
 iosMain
 androidMain
 Settingsのインスタンスの初期化

  47. Keychain、SharedPreference(暗号化有り)
 • アクセス用の共通クラスからアクセス 
 47 各プラットフォーム毎にactualで実装 したSettingsが適用される 


  48. Keychain、SharedPreference(暗号化有り)取り扱い時の注意事項
 48 • KeychainはまだExperimentalな機能 
 ◦ とはいえtouchlab※1 のブログでは「数多くのプロジェクトで導入しているが不具合は 
 上がっていない」との記載有り

    
 • Access Groupの設定は未対応
 ◦ 複数Access Groupに対応したアプリでの挙動が保証できない 
 • kSecAttrAccessibleの指定不可
 ◦ keychainへのアクセスタイミングに制限をかけたい場合は使用できないため、iOSアプリで実装する必要 がある
 ※1: KMM開発のエキスパート集団。KMMテンプレートプロジェクトや技術ブログ運営など、KMMに関す る情報を幅広く取り扱っている 

  49. DBやUserDefaults、Keychain、SharedPreferenceにアクセスできる?
 49 DB、その他ローカルデータ保存領域への値保存・取得は可能 
 完全な共通化はできないが、設計次第でほぼ共通化することが可能 


  50. KMP採用にあたって、我々も不安がたくさんあった
 50 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は

    できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?

  51. Kotlin、Gradle、KMP対応ライブラリの知識が必要。ただし、習得しながら対応を進めることも可能。 
 iOSの知識に追加でどんな知識が必要か?
 ※僕たちがKMPを使ったコードリニューアル・リアーキテクチャを1年以上続けてきて感じたことです
 51 Kotlin ・コードを書くのに必要 Gradle ・プロジェクトの初期設定 ・Kotlinバージョンアップやライブラリ導入

    ・Gradle SyncやBuildなど KMP対応ライブラリ ・KMP対応の公式ライブラリなどの使用
  52. Kotlinの知識について。
 • KMPはKotlinで記述するのでiOSエンジニアでもKotlinを書く必要がある 
 • しかし、AndroidのUIに関する知識はほとんど不要 
 • ビジネスロジックを書くためのKotlin知識のみが必要 


    ※KotlinはSwiftの言語機能と似ている点も多く、すぐに慣れると思う(個人的な感想です) 
 iOSの知識に追加でどんな知識が必要か?
 52
  53. Gradleの知識について。
 • KMPの設定はGradleで行われ、Kotlinのバージョンアップやライブラリ導入などで記述が必要になる 
 ◦ 特に初期段階は、モジュール構成を変更したり、設定を見直したりすることが多くなる 
 • また、Gradle SyncやBuildを使った開発の流れを把握しておく必要もあり

    
 • 基本的なものはチュートリアルやサンプルがあるので、やりながら習得すれば良い 
 iOSの知識に追加でどんな知識が必要か?
 53
  54. KMP対応ライブラリの知識について。 
 • 共通コード部分ではKMPに対応したライブラリを使用することになる 
 ◦ それらの多くは、JetBrainsが公式でライブラリを提供してくれている 
 ▪ KtorやSerialization、Coroutinesなど

    
 • これらのライブラリの使用方法などを理解しておく必要がある 
 • ただし、これらは初めから知識をつけておく必要はなく、ライブラリを使用しながら習得すれば良い 
 iOSの知識に追加でどんな知識が必要か?
 54
  55. Androidの機能(SharedPreferencesなど)の知識については・・・ 
 • 知識があることに越したことはないが、 必須ではない
 • ライブラリを使用する上では、理解しておいたほうが良いだろう 
 iOSの知識に追加でどんな知識が必要か?
 55

  56. Kotlin、Gradle、KMP対応ライブラリの知識が必要。ただし、習得しながら対応を進めることも可能。 
 iOSの知識に追加でどんな知識が必要か?
 ※僕たちがKMPを使ったコードリニューアル・リアーキテクチャを1年以上続けてきて感じたことです
 56

  57. まとめ
 57

  58. 問題なく実装できている
 
 • 多少不便を感じる箇所や運用でカバーしている部分はあるものの、大規模アプリでも問題無く開発 できている
 ◦ (少なくとも我々のアプリでは)実現できない仕様は現状無い 
 ◦ 想定したとおりのコード共通化ができ、適切な責務分割ができている

    
 • iOSエンジニアでも大きくつまづくこと無く実装できている 
 58
  59. KMPの導入事例を増やせば情報共有の機会も増える!
 踏み切れなかったあなたもぜひチャレンジしてみましょう!
 少しずつでも導入してみて、KMPを盛り上げましょう✨
 59

  60. 経験者がいないと不安…であれば、
 ぜひ一緒に開発しましょう!
 60 興味がある方はコチラ!


  61. 参考
 • https://www.recruit.co.jp/service/gourmet/02/index.html
 • https://dev.to/touchlab/encrypted-key-value-store-in-kotlin-multiplatform-2hnk
 • https://kotlinlang.org/docs/multiplatform.html
 • https://kotlinlang.org/lp/mobile/
 •

    https://kotlinlang.org/docs/mobile/connect-to-platform-specific-apis.html
 • https://www.irasutoya.com/2014/09/blog-post_849.html
 • https://carbon.now.sh/
 • https://touchlab.co/
 • https://github.com/cashapp/sqldelight
 • https://github.com/realm/realm-kotlin
 • https://github.com/russhwolf/multiplatform-settings
 • https://github.com/ktorio/ktor
 • https://github.com/Kotlin/kotlinx.serialization
 • https://github.com/Kotlin/kotlinx.coroutines
 61
  62. Appendix
 62

  63. ロジック共通化についての補足説明
 63

  64. • 例えば、APIへの認証キーのような共通化できない定義の ものは、expect/actualを使って解決することで共通化でき なくとも可読性が保たれる
 • 先程のiosMain/androidMainに定義されている大半のコー ドはこのような共通化できない定義自体が記述されている 
 ロジック共通化は結局うまくできるのか?
 64

    ApiKeyを使用する際は、iOS/Androidを意 識することなく使用できる
 expect/actual定義

  65. ロジック共通化は結局うまくできるのか?
 • 例えば、共通部分からFirebase Realtime Databaseにアクセスする場合、RealtimeDatabaseClientと いうinterfaceを使うようにしている 
 • その実装はiOS/Androidに存在しており、インスタンスをinjectする仕組み 


    65 commonMainはinterfaceを提供 
 iOSアプリがinterfaceを実装 
 Androidアプリがinterfaceを実装 

  66. ObjCヘッダーによるIFの使いづらさについての補足説明
 66

  67. Kotlin側のinterface内にメソッドのデフォルト実装をすると、iOSではprotocolのrequired functionに変換さ れてしまい実装を求められてしまう 
 
 interface内にデフォルト実装問題
 67 Interfaceのデフォルト実装 


  68. interface内にデフォルト実装問題
 68 iOSではデフォルト実装が適用されず、実装を強制される 


  69. interface内にデフォルト実装問題(解決策)
 • Kotlinの拡張関数機能(Swiftのextensionのようなもの)を使い、デフォルト実装にしていたものを拡 張関数として実装
 ◦ interfaceのデフォルト実装だったメソッドをAnalyticsClientの拡張関数として実装すると、iOSで実装を強 制されることが無くなる 
 69 拡張関数として実装

  70. inline class問題
 • Obj-Cでinline class(inline展開可能なクラス)が解釈できず、iOSからはラッパークラスを用意する必 要がある
 • 日付を扱うライブラリとしてklockを使用しているが、klockのDateTimeやDate, Timeはinline classで

    実装されているためiOSで日付時間を扱うことができなかった。 
 
 70
  71. inline class問題(解決策)
 • klockにはinline classをラップしたWDateTimeやWDateが実装されているため、それらをiOSから見え るようにし、iOSからはラップされたクラスを使用するようにした 
 71

  72. クラスが階層的に表現できない問題
 • data classを階層構造にした場合(要確認)、型名が親のデータクラス名と連結された名前になる 
 72 class > class >

    data class 

  73. クラスが階層的に表現できない問題
 • data classを階層構造にした場合(要確認)、型名が親のデータクラス名と連結された名前になる 
 73 正しく階層関係になっている 
 outputChildとoutputGrandChildがひと繋ぎに なっている


  74. クラスが階層的に表現できない問題(解決策)
 • data classを使わないしか解決策は無いが利便性は落ちるため、我々のプロジェクトでは許容とし ている
 74

  75. Enum問題
 • SharedKotlinEnumのサブクラスになってしまい、NS_ENUMにならない 
 
 75

  76. Enum問題
 • enumの網羅性を判定できず、defaultの記述が必須となる 
 
 76

  77. Enum問題
 • NS_ENUMを出力するFeature Requestは上がっているが、対応バージョンは未定 
 ◦ https://youtrack.jetbrains.com/issue/KT-48068 
 77

  78. SQLDelightの使い方補足
 78

  79. SQLDelightの使い方
 • SQLDelightプラグインを読み込んでDatabaseを定義 
 ◦ 共通モジュールのbuild.gradleに記載(共通化可能) 
 79

  80. SQLDelightの使い方
 • .sqファイルにSQL文を定義しビルドタスクを実行 
 ◦ SQLDelightがDB操作のためのKotlinファイルを自動生成する 
 ◦ スキーマ定義や使うSQLがOS間で同一であれば共通化可能 


    80 テーブルのCREATE 
 各種SQLと、Kotlinから呼ぶ際 のメソッド名定義

  81. SQLDelight補足
 • CoroutineのFlowもサポートされているからDBの値の変更監視・通知も実現可能 
 81