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

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

Kenzo Nirasawa
September 18, 2021

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

Kenzo Nirasawa

September 18, 2021
Tweet

Other Decks in Programming

Transcript

  1. iOSエンジニアがKMPで大規模アプリの

    ロジック共通化をしてうまくできている話

    (株)リクルート 韮澤 賢三

    浅井 徹 

    1

    View Slide

  2. はじめに

    2

    View Slide

  3. 自己紹介

    韮澤 賢三(@nirazo)

    株式会社リクルート 

    iOSエンジニア歴約7年

    ホットペッパーグルメアプリ開発チームリーダー兼アプリリプレイ
    スプロジェクトリーダー

    略歴

    2012年4月 Webサービス企業に新卒入社 

    2015年11月 リクルートライフスタイル中途入社 

    2019年10月 ホットペッパーグルメ開発チーム参画 

    3

    View Slide

  4. 浅井 徹(@trsxxii)

    株式会社リクルート 

    iOSエンジニア歴 6~7年

    ホットペッパーグルメアプリ KMP開発チームリーダー

    略歴

    2014年4月 Webサービス企業に新卒入社 

    2019年11月 リクルートライフスタイルに中途入社 

    自己紹介

    4
    浅井さんの写真だよ

    View Slide

  5. 本発表のゴール

    5
    Kotlin Multiplatformに興味はあるけど踏み切れない、そんな方の不安を解消し、
    iOSエンジニアでもやれるんだという気持ちになってもらう


    View Slide

  6. ● ホットペッパーグルメについて

    ● Kotlin Multiplatform Projectとは

    ● ホットペッパーグルメとKMP

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

    ○ ロジック共通化はうまくできるのか? 

    ○ ObjCヘッダーでIFが使いづらいのでは? 

    ○ DBやUserDefaults、Keychainにアクセスできるのか? 

    ○ iOSの知識に追加でどんな知識が必要か? 

    ● まとめ

    アジェンダ


    6

    View Slide

  7. リクルートは多数のサービスを運営しています

    7

     メディア&ソリューションSBU 
 HRテクノロジーSBU
 人材派遣SBU

    販促領域
 人材領域
 国内派遣
 海外派遣

    etc...

    選択・意思決定を支援する情報サービスを提供し、

    「まだ、ここにない、出会い。より速く、シンプルに、もっと近くに」を実現する

    View Slide

  8. ホットペッパーグルメを開発しています



    8

    View Slide

  9. Kotlin Multiplatform Projectとは

    9

    View Slide

  10. KMPとは - 概要

    ● Kotlin Multiplatform Project(以後KMP)とは、Kotlinで記述されたコードを

    異なるプラットフォーム用にコンパイルできるプロジェクトのこと

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


    View Slide

  11. KMPとは - KMM

    ● その中でも、KMPの一つのユースケースである、
    iOS/Androidのコード共有を実現することを

    Kotlin Multiplatform Mobile(KMM)と言う

    ○ 今回説明することは厳密にはKMMに関する内容


    ● FlutterやReactNativeなどとは違い、

    ビジネスロジック部分のみを共通化する

    ● あくまでもViewは各プラットフォームで実装する

    11
    引用元:https://kotlinlang.org/lp/mobile/ 


    View Slide

  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 


    View Slide

  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 


    View Slide

  14. ● 前述したApple Frameworkで生成されるバイナリのヘッダーはObjective-Cヘッダーになっている

    ○ iOS開発ではObjective-Cヘッダーを通して、Swiftから使用することとなる 

    ● できるだけSwiftらしいInterfaceになるように多くのAttributeが指定されている

    KMPとは - iOS開発

    14
    Swiftから使うための命名

    Nullable/NonNull指定


    View Slide

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

    15

    View Slide

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

    ● ホットペッパーグルメアプリはリリースから10年以上が経過し、開発を継続していくに

    あたっての課題が浮き彫りになってきた

    ○ 10年以上が経過した今も大規模な設計変更等は無く、リリース当初の実装に継ぎ足し開発を 

    行ってきた

    16
    ソースコードの
    肥大化
    ソースコードの
    複雑化
    開発スピードの鈍化
    障害防止の
    難度上昇

    View Slide

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

    ● 今後の安定した開発のため、コードリニューアル・リアーキテクチャを決断し、

    クロスプラットフォーム技術の検討を実施

    ○ 開発工数の削減

    ○ 予期せぬOS間差分を防ぐことによる品質の安定化 


    ● クロスプラットフォームの中でもKotlin Multiplatformを採用

    ○ UIは各プラットフォームに準拠させたい 

    ○ Kotlinで書けるためキャッチアップの難易度はそこまで高くないと判断 

    17

    View Slide

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

    ● iOS / Android / Shared (KMP担当)の3チーム構成でプロジェクト進行中

    ○ iOS/Androidはそれぞれ最大8名、Sharedは最大4名 

    18
    Android
    iOS
    Shared
    フェーズによってSharedからiOS,
    Androidへ移籍


    View Slide

  19. KMP採用にあたって、我々も不安がたくさんあった

    19
    永続化領域やKeychainな
    どにはアクセスできるのだ
    ろうか?

    iOS開発の知識以外に
    どんな知識を身につける
    必要があるのだろうか? 

    ちゃんとロジック共通化は
    できるのだろうか?(実はif
    文がたくさんなんてことは
    …)

    Objective-Cのヘッダー だ
    からSwiftから使いづらくて
    嫌になるんじゃないだろう
    か?


    View Slide

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

    20

    View Slide

  21. KMP採用にあたって、我々も不安がたくさんあった

    21
    永続化領域やKeychainな
    どにはアクセスできるのだ
    ろうか?

    iOS開発の知識以外に
    どんな知識を身につける
    必要があるのだろうか? 

    ちゃんとロジック共通化は
    できるのだろうか?(実はif
    文がたくさんなんてことは
    …)

    Objective-Cのヘッダー だ
    からSwiftから使いづらくて
    嫌になるんじゃないだろう
    か?


    View Slide

  22. ロジック共通化は結局うまくできるのか?

    ● ホットペッパーグルメのアーキテクチャは以下のようになっている

    ○ KMPを使用したロジックの共通化部分は赤枠部分 

    22

    View Slide

  23. ロジック共通化は結局うまくできるのか?

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

    View Slide

  24. ロジック共通化は結局うまくできるのか?

    ● KMP対象のビジネスロジック部分のコード行数比率を見ると、ほぼすべてのコードを

    共通化することに成功している

    ● commonMainの中にはOSによるif文が存在しているが、それもかなり少ない

    24
    対象
 コード行数比率

    commonMain
 99.13%

    androidMain
 0.45%

    iosMain
 0.42%


    View Slide

  25. ロジック共通化は結局うまくできるのか?

    25
    ● 最も差分が出やすいライブラリ使用部分の一部を共通化しない選択をしている

    ● 同じ機能の3rd Partyライブラリを使う場合に、共通部分にinterfaceを持たせて、

    各アプリコードに実装する判断をした

    ○ 共通化できないものを無理に共通コードには入れない方針 

    ○ interface提供しているライブラリの数も7種類と少ない 

    ※ネットワークや永続化領域へのアクセスなど主要なものは公式ライブラリを使用している

    commonMain

    Android専用

    ライブラリ

    iOSアプリ
 Androidアプリ

    iOS専用

    ライブラリ

    interface

    共通コード

    interface提供するライブラリの種類 
 数

    ログ系ライブラリ
 3種類

    社内ライブラリ
 1種類

    3rd Partyライブラリ
 3種類


    View Slide

  26. ロジック共通化は結局うまくできるのか?

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

    View Slide

  27. KMP採用にあたって、我々も不安がたくさんあった

    27
    永続化領域やKeychainな
    どにはアクセスできるのだ
    ろうか?

    iOS開発の知識以外に
    どんな知識を身につける
    必要があるのだろうか? 

    ちゃんとロジック共通化は
    できるのだろうか?(実はif
    文がたくさんなんてことは
    …)

    Objective-Cのヘッダー だ
    からSwiftから使いづらくて
    嫌になるんじゃないだろう
    か?


    View Slide

  28. ObjCヘッダーでIFが使いづらい?

    KMP側の実装やiOS側の実装の工夫により、膨大な工数やアーキテクチャ変更無く回避可能 

    28
    使いづらい部分はあるものの、そもそも機能が動かない・アーキテクチャが崩壊するといったレベ
    ルの問題は発生していない

    View Slide

  29. ObjCヘッダーでIFが使いづらい?

    大きな問題は発生していないものの、そもそもKotlin <-> Obj-Cの変換時の制約のために、

    シンプルな実装にできない箇所が存在する

    ● Generics定義が再帰的になる場合、iOSから見るとAnyになってしまう

    ● 無限アンダースコア問題

    ● Kotlinのinterface内にメソッドをデフォルト実装するとiOSでは実装を求められてしまう

    ● inline classを解釈できない

    ● クラスが階層的に表現できない問題

    ● Enum問題

    29

    View Slide

  30. ObjCヘッダーでIFが使いづらい?

    大きな問題は発生していないものの、そもそもKotlin <-> Obj-Cの変換時の制約のために、

    シンプルな実装にできない箇所が存在する

    ● Generics定義が再帰的になる場合、iOSから見るとAnyになってしまう

    ● 無限アンダースコア問題

    ● Kotlinのinterface内にメソッドをデフォルト実装するとiOSでは実装を求められてしまう

    ● inline classを解釈できない

    ● クラスが階層的に表現できない問題

    ● Enum問題

    30

    View Slide

  31. ● Kotlin側でGenericsが階層構造になっている場合、iOSから見るとAny(id型)になってしまう

    Generics階層構造でAny問題

    31
    Generics

    Generics in Generics 


    View Slide

  32. Generics階層構造でAny問題(解決策)

    ● ResultsのTに入る型をジェネリクスを含むクラスをやめて、ジェネリクスを含まない型に変更
    することで回避した

    32
    Genericsをラップするclassを作成して
    Resultsに入れる


    View Slide

  33. Generics再帰でAny問題

    ● Issueが上がっているが対応バージョンは未定

    ○ https://youtrack.jetbrains.com/issue/KT-41847 

    33

    View Slide

  34. 無限アンダースコア問題

    ● 同名・同引数名のメソッドが複数ある場合、Swiftコードでは引数にアンダースコアが入ったメソッド
    になる

    34
    引数名にアンダースコアが入ってしまう 

    同名・同引数名のメソッド 


    View Slide

  35. 無限アンダースコア問題

    ● KMPではKotlin <-> Obj-C変換にあたり、コンパイル時の名前空間被りを引数名に

    アンダースコアをつけることで解消している

    ○ Issueは上がっているが対応バージョンは未定 

    ■ https://youtrack.jetbrains.com/issue/KT-43087 

    ● 我々のコードでは全UseCaseがexecute(input: Input)という統一の名前のメソッドを

    持つという規約があったため、この影響を受けてしまった


    35

    View Slide

  36. 無限アンダースコア問題(解決策)

    ● 引数名をinputからUseCaseに応じたInput名に変更することで名前被りを防いだ



    36
    UseCase毎にinputの引数名を変
    更


    View Slide

  37. ObjCヘッダーでIFが使いづらい?

    KMP側の実装やiOS側の実装の工夫により、膨大な工数やアーキテクチャ変更無く回避可能 

    37
    使いづらい部分はあるものの、そもそも機能が動かない・アーキテクチャが崩壊するといったレベ
    ルの問題は発生していない

    View Slide

  38. KMP採用にあたって、我々も不安がたくさんあった

    38
    永続化領域やKeychainな
    どにはアクセスできるのだ
    ろうか?

    iOS開発の知識以外に
    どんな知識を身につける
    必要があるのだろうか? 

    ちゃんとロジック共通化は
    できるのだろうか?(実はif
    文がたくさんなんてことは
    …)

    Objective-Cのヘッダー だ
    からSwiftから使いづらくて
    嫌になるんじゃないだろう
    か?


    View Slide

  39. DBやUserDefaults、Keychain、SharedPreferenceにアクセスできる?

    39
    DB、その他ローカルデータ※
    保存領域への値保存・取得は可能

    完全な共通化はできないが、設計次第でほぼ共通化することが可能

    保存領域 使えるライブラリ
    DBアクセス ● SQLDelight
    ● Realm
    ローカルデータアクセス ● multiplatform-settings
    ※ UserDefaults, Keychain, SharedPreferenceを便宜上まとめてローカルデータと呼ぶ


    View Slide

  40. DBへのアクセス

    ● SQLDelightというライブラリを使い、SQLiteをKMPで利用可能

    ● RealmもKMPで利用できるライブラリを開発中だが、未だα版でありSQLDelightほど

    市民権を得ていない

    ○ スター数はSQLDelight: 約4100, Realm: 約300 (8/23現在) 

    ● ホットペッパーグルメではSQLDelightを採用した

    40

    View Slide

  41. SQLDelightの使い方と共通化可否

    ● DBのインスタンス生成コード(各OS1行程度)以外の処理は全て共通化が可能!

    41
    やること概要 やること詳細 共通化可否
    スキーマ定義・SQL文定義 スキーマ定義ファイルに SQL文を記述 可
    DBのインスタンス作成 OS毎に初期化処理を実装 不可
    DB操作用コード実装 自動生成されたメソッド経由で DB操作処理を
    実装

    View Slide

  42. SQLDelightの使い方

    ● DBのインスタンス作成をOS毎に実装

    ○ プラットフォーム毎にDriverが用意されているため、ここは共通化不可 

    42
    expectでdb生成メソッド定義

    androidMain

    iosMain


    View Slide

  43. SQLDelightの使い方

    ● sqファイルから自動生成されたメソッドを使ってアプリからDBを操作するコードを書く

    43
    “テーブル名”Queries経由で、sq
    ファイルに定義したメソッドを呼
    び出せる


    View Slide

  44. ローカルデータアクセスの共通化可否

    44
    ● multiplatform-settingsというライブラリでアクセス可能

    ● 暗号化無しの場合はコードを完全に共通化可能

    ● 暗号化有りの場合もオブジェクトのインスタンス生成コード(数行程度)以外の処理は全て共通化が
    可能

    やること概要 共通化可否
    UserDefaults,
    SharedPreference
    オブジェクトのインスタンス生成 可
    オブジェクトへのRead, Write処理 可
    Keychain, 暗号化有り
    SharedPreference
    オブジェクトのインスタンス生成 不可
    オブジェクトへのRead, Write処理 可

    View Slide

  45. UserDefaults、SharedPreference(暗号化無し)

    ● シンプルにSettingsインスタンスを生成し、put, getするのみ

    ○ 共通化も可能

    45
    Settingsのインスタンスを作成 

    シンプルにget, put


    View Slide

  46. Keychain、SharedPreference(暗号化有り)

    ● expect classとしてSettings型のプロパティを持つクラスを定義し、OS毎に初期化処理を実装

    46
    expectSettings変数

    iosMain

    androidMain
 Settingsのインスタンスの初期化 


    View Slide

  47. Keychain、SharedPreference(暗号化有り)

    ● アクセス用の共通クラスからアクセス

    47
    各プラットフォーム毎にactualで実装
    したSettingsが適用される 


    View Slide

  48. Keychain、SharedPreference(暗号化有り)取り扱い時の注意事項

    48
    ● KeychainはまだExperimentalな機能

    ○ とはいえtouchlab※1
    のブログでは「数多くのプロジェクトで導入しているが不具合は 

    上がっていない」との記載有り 

    ● Access Groupの設定は未対応

    ○ 複数Access Groupに対応したアプリでの挙動が保証できない 

    ● kSecAttrAccessibleの指定不可

    ○ keychainへのアクセスタイミングに制限をかけたい場合は使用できないため、iOSアプリで実装する必要
    がある

    ※1: KMM開発のエキスパート集団。KMMテンプレートプロジェクトや技術ブログ運営など、KMMに関す
    る情報を幅広く取り扱っている 


    View Slide

  49. DBやUserDefaults、Keychain、SharedPreferenceにアクセスできる?

    49
    DB、その他ローカルデータ保存領域への値保存・取得は可能

    完全な共通化はできないが、設計次第でほぼ共通化することが可能

    View Slide

  50. KMP採用にあたって、我々も不安がたくさんあった

    50
    永続化領域やKeychainな
    どにはアクセスできるのだ
    ろうか?

    iOS開発の知識以外に
    どんな知識を身につける
    必要があるのだろうか? 

    ちゃんとロジック共通化は
    できるのだろうか?(実はif
    文がたくさんなんてことは
    …)

    Objective-Cのヘッダー だ
    からSwiftから使いづらくて
    嫌になるんじゃないだろう
    か?


    View Slide

  51. Kotlin、Gradle、KMP対応ライブラリの知識が必要。ただし、習得しながら対応を進めることも可能。

    iOSの知識に追加でどんな知識が必要か?

    ※僕たちがKMPを使ったコードリニューアル・リアーキテクチャを1年以上続けてきて感じたことです

    51
    Kotlin ・コードを書くのに必要
    Gradle
    ・プロジェクトの初期設定
    ・Kotlinバージョンアップやライブラリ導入
    ・Gradle SyncやBuildなど
    KMP対応ライブラリ ・KMP対応の公式ライブラリなどの使用

    View Slide

  52. Kotlinの知識について。

    ● KMPはKotlinで記述するのでiOSエンジニアでもKotlinを書く必要がある

    ● しかし、AndroidのUIに関する知識はほとんど不要

    ● ビジネスロジックを書くためのKotlin知識のみが必要

    ※KotlinはSwiftの言語機能と似ている点も多く、すぐに慣れると思う(個人的な感想です)

    iOSの知識に追加でどんな知識が必要か?

    52

    View Slide

  53. Gradleの知識について。

    ● KMPの設定はGradleで行われ、Kotlinのバージョンアップやライブラリ導入などで記述が必要になる

    ○ 特に初期段階は、モジュール構成を変更したり、設定を見直したりすることが多くなる 

    ● また、Gradle SyncやBuildを使った開発の流れを把握しておく必要もあり

    ● 基本的なものはチュートリアルやサンプルがあるので、やりながら習得すれば良い

    iOSの知識に追加でどんな知識が必要か?

    53

    View Slide

  54. KMP対応ライブラリの知識について。

    ● 共通コード部分ではKMPに対応したライブラリを使用することになる

    ○ それらの多くは、JetBrainsが公式でライブラリを提供してくれている 

    ■ KtorやSerialization、Coroutinesなど 

    ● これらのライブラリの使用方法などを理解しておく必要がある

    ● ただし、これらは初めから知識をつけておく必要はなく、ライブラリを使用しながら習得すれば良い

    iOSの知識に追加でどんな知識が必要か?

    54

    View Slide

  55. Androidの機能(SharedPreferencesなど)の知識については・・・

    ● 知識があることに越したことはないが、
    必須ではない

    ● ライブラリを使用する上では、理解しておいたほうが良いだろう

    iOSの知識に追加でどんな知識が必要か?

    55

    View Slide

  56. Kotlin、Gradle、KMP対応ライブラリの知識が必要。ただし、習得しながら対応を進めることも可能。

    iOSの知識に追加でどんな知識が必要か?

    ※僕たちがKMPを使ったコードリニューアル・リアーキテクチャを1年以上続けてきて感じたことです

    56

    View Slide

  57. まとめ

    57

    View Slide

  58. 問題なく実装できている


    ● 多少不便を感じる箇所や運用でカバーしている部分はあるものの、大規模アプリでも問題無く開発
    できている

    ○ (少なくとも我々のアプリでは)実現できない仕様は現状無い 

    ○ 想定したとおりのコード共通化ができ、適切な責務分割ができている 

    ● iOSエンジニアでも大きくつまづくこと無く実装できている

    58

    View Slide

  59. KMPの導入事例を増やせば情報共有の機会も増える!

    踏み切れなかったあなたもぜひチャレンジしてみましょう!

    少しずつでも導入してみて、KMPを盛り上げましょう✨

    59

    View Slide

  60. 経験者がいないと不安…であれば、

    ぜひ一緒に開発しましょう!

    60
    興味がある方はコチラ!


    View Slide

  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

    View Slide

  62. Appendix

    62

    View Slide

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

    63

    View Slide

  64. ● 例えば、APIへの認証キーのような共通化できない定義の
    ものは、expect/actualを使って解決することで共通化でき
    なくとも可読性が保たれる

    ● 先程のiosMain/androidMainに定義されている大半のコー
    ドはこのような共通化できない定義自体が記述されている

    ロジック共通化は結局うまくできるのか?

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


    View Slide

  65. ロジック共通化は結局うまくできるのか?

    ● 例えば、共通部分からFirebase Realtime Databaseにアクセスする場合、RealtimeDatabaseClientと
    いうinterfaceを使うようにしている

    ● その実装はiOS/Androidに存在しており、インスタンスをinjectする仕組み

    65
    commonMainはinterfaceを提供 

    iOSアプリがinterfaceを実装 

    Androidアプリがinterfaceを実装 


    View Slide

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

    66

    View Slide

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


    interface内にデフォルト実装問題

    67
    Interfaceのデフォルト実装 


    View Slide

  68. interface内にデフォルト実装問題

    68
    iOSではデフォルト実装が適用されず、実装を強制される 


    View Slide

  69. interface内にデフォルト実装問題(解決策)

    ● Kotlinの拡張関数機能(Swiftのextensionのようなもの)を使い、デフォルト実装にしていたものを拡
    張関数として実装

    ○ interfaceのデフォルト実装だったメソッドをAnalyticsClientの拡張関数として実装すると、iOSで実装を強
    制されることが無くなる 

    69
    拡張関数として実装 


    View Slide

  70. inline class問題

    ● Obj-Cでinline class(inline展開可能なクラス)が解釈できず、iOSからはラッパークラスを用意する必
    要がある

    ● 日付を扱うライブラリとしてklockを使用しているが、klockのDateTimeやDate, Timeはinline classで
    実装されているためiOSで日付時間を扱うことができなかった。


    70

    View Slide

  71. inline class問題(解決策)

    ● klockにはinline classをラップしたWDateTimeやWDateが実装されているため、それらをiOSから見え
    るようにし、iOSからはラップされたクラスを使用するようにした

    71

    View Slide

  72. クラスが階層的に表現できない問題

    ● data classを階層構造にした場合(要確認)、型名が親のデータクラス名と連結された名前になる

    72
    class > class > data class 


    View Slide

  73. クラスが階層的に表現できない問題

    ● data classを階層構造にした場合(要確認)、型名が親のデータクラス名と連結された名前になる

    73
    正しく階層関係になっている 

    outputChildとoutputGrandChildがひと繋ぎに
    なっている


    View Slide

  74. クラスが階層的に表現できない問題(解決策)

    ● data classを使わないしか解決策は無いが利便性は落ちるため、我々のプロジェクトでは許容とし
    ている

    74

    View Slide

  75. Enum問題

    ● SharedKotlinEnumのサブクラスになってしまい、NS_ENUMにならない


    75

    View Slide

  76. Enum問題

    ● enumの網羅性を判定できず、defaultの記述が必須となる


    76

    View Slide

  77. Enum問題

    ● NS_ENUMを出力するFeature Requestは上がっているが、対応バージョンは未定

    ○ https://youtrack.jetbrains.com/issue/KT-48068 

    77

    View Slide

  78. SQLDelightの使い方補足

    78

    View Slide

  79. SQLDelightの使い方

    ● SQLDelightプラグインを読み込んでDatabaseを定義

    ○ 共通モジュールのbuild.gradleに記載(共通化可能) 

    79

    View Slide

  80. SQLDelightの使い方

    ● .sqファイルにSQL文を定義しビルドタスクを実行

    ○ SQLDelightがDB操作のためのKotlinファイルを自動生成する 

    ○ スキーマ定義や使うSQLがOS間で同一であれば共通化可能 

    80
    テーブルのCREATE 

    各種SQLと、Kotlinから呼ぶ際
    のメソッド名定義


    View Slide

  81. SQLDelight補足

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

    81

    View Slide