Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

はじめに
 2

Slide 3

Slide 3 text

自己紹介
 韮澤 賢三(@nirazo)
 株式会社リクルート 
 iOSエンジニア歴約7年
 ホットペッパーグルメアプリ開発チームリーダー兼アプリリプレイ スプロジェクトリーダー
 略歴
 2012年4月 Webサービス企業に新卒入社 
 2015年11月 リクルートライフスタイル中途入社 
 2019年10月 ホットペッパーグルメ開発チーム参画 
 3

Slide 4

Slide 4 text

浅井 徹(@trsxxii)
 株式会社リクルート 
 iOSエンジニア歴 6~7年
 ホットペッパーグルメアプリ KMP開発チームリーダー 
 略歴
 2014年4月 Webサービス企業に新卒入社 
 2019年11月 リクルートライフスタイルに中途入社 
 自己紹介
 4 浅井さんの写真だよ

Slide 5

Slide 5 text

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


Slide 6

Slide 6 text

● ホットペッパーグルメについて
 ● Kotlin Multiplatform Projectとは
 ● ホットペッパーグルメとKMP
 ● 我々の不安要素は実際どうだったのか 
 ○ ロジック共通化はうまくできるのか? 
 ○ ObjCヘッダーでIFが使いづらいのでは? 
 ○ DBやUserDefaults、Keychainにアクセスできるのか? 
 ○ iOSの知識に追加でどんな知識が必要か? 
 ● まとめ
 アジェンダ
 
 6

Slide 7

Slide 7 text

リクルートは多数のサービスを運営しています
 7
  メディア&ソリューションSBU 
 HRテクノロジーSBU
 人材派遣SBU
 販促領域
 人材領域
 国内派遣
 海外派遣
 etc...
 選択・意思決定を支援する情報サービスを提供し、
 「まだ、ここにない、出会い。より速く、シンプルに、もっと近くに」を実現する

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Kotlin Multiplatform Projectとは
 9

Slide 10

Slide 10 text

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


Slide 11

Slide 11 text

KMPとは - KMM
 ● その中でも、KMPの一つのユースケースである、 iOS/Androidのコード共有を実現することを 
 Kotlin Multiplatform Mobile(KMM)と言う 
 ○ 今回説明することは厳密にはKMMに関する内容
 
 ● FlutterやReactNativeなどとは違い、 
 ビジネスロジック部分のみを共通化する 
 ● あくまでもViewは各プラットフォームで実装する 
 11 引用元:https://kotlinlang.org/lp/mobile/ 


Slide 12

Slide 12 text

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 


Slide 13

Slide 13 text

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 


Slide 14

Slide 14 text

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


Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

ホットペッパーグルメとKMP
 ● ホットペッパーグルメアプリはリリースから10年以上が経過し、開発を継続していくに 
 あたっての課題が浮き彫りになってきた 
 ○ 10年以上が経過した今も大規模な設計変更等は無く、リリース当初の実装に継ぎ足し開発を 
 行ってきた
 16 ソースコードの 肥大化 ソースコードの 複雑化 開発スピードの鈍化 障害防止の 難度上昇

Slide 17

Slide 17 text

ホットペッパーグルメとKMP
 ● 今後の安定した開発のため、コードリニューアル・リアーキテクチャを決断し、 
 クロスプラットフォーム技術の検討を実施 
 ○ 開発工数の削減
 ○ 予期せぬOS間差分を防ぐことによる品質の安定化 
 
 ● クロスプラットフォームの中でもKotlin Multiplatformを採用 
 ○ UIは各プラットフォームに準拠させたい 
 ○ Kotlinで書けるためキャッチアップの難易度はそこまで高くないと判断 
 17

Slide 18

Slide 18 text

ホットペッパーグルメとKMP
 ● iOS / Android / Shared (KMP担当)の3チーム構成でプロジェクト進行中 
 ○ iOS/Androidはそれぞれ最大8名、Sharedは最大4名 
 18 Android iOS Shared フェーズによってSharedからiOS, Androidへ移籍


Slide 19

Slide 19 text

KMP採用にあたって、我々も不安がたくさんあった
 19 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?


Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

KMP採用にあたって、我々も不安がたくさんあった
 21 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?


Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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


Slide 25

Slide 25 text

ロジック共通化は結局うまくできるのか?
 25 ● 最も差分が出やすいライブラリ使用部分の一部を共通化しない選択をしている 
 ● 同じ機能の3rd Partyライブラリを使う場合に、共通部分にinterfaceを持たせて、 
 各アプリコードに実装する判断をした 
 ○ 共通化できないものを無理に共通コードには入れない方針 
 ○ interface提供しているライブラリの数も7種類と少ない 
 ※ネットワークや永続化領域へのアクセスなど主要なものは公式ライブラリを使用している 
 commonMain
 Android専用
 ライブラリ
 iOSアプリ
 Androidアプリ
 iOS専用
 ライブラリ
 interface
 共通コード
 interface提供するライブラリの種類 
 数
 ログ系ライブラリ
 3種類
 社内ライブラリ
 1種類
 3rd Partyライブラリ
 3種類


Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

KMP採用にあたって、我々も不安がたくさんあった
 27 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?


Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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


Slide 32

Slide 32 text

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


Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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


Slide 35

Slide 35 text

無限アンダースコア問題
 ● KMPではKotlin <-> Obj-C変換にあたり、コンパイル時の名前空間被りを引数名に 
 アンダースコアをつけることで解消している 
 ○ Issueは上がっているが対応バージョンは未定 
 ■ https://youtrack.jetbrains.com/issue/KT-43087 
 ● 我々のコードでは全UseCaseがexecute(input: Input)という統一の名前のメソッドを 
 持つという規約があったため、この影響を受けてしまった 
 
 35

Slide 36

Slide 36 text

無限アンダースコア問題(解決策)
 ● 引数名をinputからUseCaseに応じたInput名に変更することで名前被りを防いだ 
 
 
 36 UseCase毎にinputの引数名を変 更


Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

KMP採用にあたって、我々も不安がたくさんあった
 38 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?


Slide 39

Slide 39 text

DBやUserDefaults、Keychain、SharedPreferenceにアクセスできる?
 39 DB、その他ローカルデータ※ 保存領域への値保存・取得は可能 
 完全な共通化はできないが、設計次第でほぼ共通化することが可能 
 保存領域 使えるライブラリ DBアクセス ● SQLDelight ● Realm ローカルデータアクセス ● multiplatform-settings ※ UserDefaults, Keychain, SharedPreferenceを便宜上まとめてローカルデータと呼ぶ


Slide 40

Slide 40 text

DBへのアクセス
 ● SQLDelightというライブラリを使い、SQLiteをKMPで利用可能 
 ● RealmもKMPで利用できるライブラリを開発中だが、未だα版でありSQLDelightほど 
 市民権を得ていない
 ○ スター数はSQLDelight: 約4100, Realm: 約300 (8/23現在) 
 ● ホットペッパーグルメではSQLDelightを採用した 
 40

Slide 41

Slide 41 text

SQLDelightの使い方と共通化可否
 ● DBのインスタンス生成コード(各OS1行程度)以外の処理は全て共通化が可能! 
 41 やること概要 やること詳細 共通化可否 スキーマ定義・SQL文定義 スキーマ定義ファイルに SQL文を記述 可 DBのインスタンス作成 OS毎に初期化処理を実装 不可 DB操作用コード実装 自動生成されたメソッド経由で DB操作処理を 実装 可

Slide 42

Slide 42 text

SQLDelightの使い方
 ● DBのインスタンス作成をOS毎に実装 
 ○ プラットフォーム毎にDriverが用意されているため、ここは共通化不可 
 42 expectでdb生成メソッド定義
 androidMain
 iosMain


Slide 43

Slide 43 text

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


Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

UserDefaults、SharedPreference(暗号化無し)
 ● シンプルにSettingsインスタンスを生成し、put, getするのみ 
 ○ 共通化も可能
 45 Settingsのインスタンスを作成 
 シンプルにget, put


Slide 46

Slide 46 text

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


Slide 47

Slide 47 text

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


Slide 48

Slide 48 text

Keychain、SharedPreference(暗号化有り)取り扱い時の注意事項
 48 ● KeychainはまだExperimentalな機能 
 ○ とはいえtouchlab※1 のブログでは「数多くのプロジェクトで導入しているが不具合は 
 上がっていない」との記載有り 
 ● Access Groupの設定は未対応
 ○ 複数Access Groupに対応したアプリでの挙動が保証できない 
 ● kSecAttrAccessibleの指定不可
 ○ keychainへのアクセスタイミングに制限をかけたい場合は使用できないため、iOSアプリで実装する必要 がある
 ※1: KMM開発のエキスパート集団。KMMテンプレートプロジェクトや技術ブログ運営など、KMMに関す る情報を幅広く取り扱っている 


Slide 49

Slide 49 text

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


Slide 50

Slide 50 text

KMP採用にあたって、我々も不安がたくさんあった
 50 永続化領域やKeychainな どにはアクセスできるのだ ろうか?
 iOS開発の知識以外に どんな知識を身につける 必要があるのだろうか? 
 ちゃんとロジック共通化は できるのだろうか?(実はif 文がたくさんなんてことは …)
 Objective-Cのヘッダー だ からSwiftから使いづらくて 嫌になるんじゃないだろう か?


Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Kotlinの知識について。
 ● KMPはKotlinで記述するのでiOSエンジニアでもKotlinを書く必要がある 
 ● しかし、AndroidのUIに関する知識はほとんど不要 
 ● ビジネスロジックを書くためのKotlin知識のみが必要 
 ※KotlinはSwiftの言語機能と似ている点も多く、すぐに慣れると思う(個人的な感想です) 
 iOSの知識に追加でどんな知識が必要か?
 52

Slide 53

Slide 53 text

Gradleの知識について。
 ● KMPの設定はGradleで行われ、Kotlinのバージョンアップやライブラリ導入などで記述が必要になる 
 ○ 特に初期段階は、モジュール構成を変更したり、設定を見直したりすることが多くなる 
 ● また、Gradle SyncやBuildを使った開発の流れを把握しておく必要もあり 
 ● 基本的なものはチュートリアルやサンプルがあるので、やりながら習得すれば良い 
 iOSの知識に追加でどんな知識が必要か?
 53

Slide 54

Slide 54 text

KMP対応ライブラリの知識について。 
 ● 共通コード部分ではKMPに対応したライブラリを使用することになる 
 ○ それらの多くは、JetBrainsが公式でライブラリを提供してくれている 
 ■ KtorやSerialization、Coroutinesなど 
 ● これらのライブラリの使用方法などを理解しておく必要がある 
 ● ただし、これらは初めから知識をつけておく必要はなく、ライブラリを使用しながら習得すれば良い 
 iOSの知識に追加でどんな知識が必要か?
 54

Slide 55

Slide 55 text

Androidの機能(SharedPreferencesなど)の知識については・・・ 
 ● 知識があることに越したことはないが、 必須ではない
 ● ライブラリを使用する上では、理解しておいたほうが良いだろう 
 iOSの知識に追加でどんな知識が必要か?
 55

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

まとめ
 57

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

KMPの導入事例を増やせば情報共有の機会も増える!
 踏み切れなかったあなたもぜひチャレンジしてみましょう!
 少しずつでも導入してみて、KMPを盛り上げましょう✨
 59

Slide 60

Slide 60 text

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


Slide 61

Slide 61 text

参考
 ● 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

Slide 62

Slide 62 text

Appendix
 62

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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


Slide 65

Slide 65 text

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


Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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


Slide 68

Slide 68 text

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


Slide 69

Slide 69 text

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


Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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


Slide 73

Slide 73 text

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


Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

SQLDelightの使い方補足
 78

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

SQLDelightの使い方
 ● .sqファイルにSQL文を定義しビルドタスクを実行 
 ○ SQLDelightがDB操作のためのKotlinファイルを自動生成する 
 ○ スキーマ定義や使うSQLがOS間で同一であれば共通化可能 
 80 テーブルのCREATE 
 各種SQLと、Kotlinから呼ぶ際 のメソッド名定義


Slide 81

Slide 81 text

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