2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
鈴木大貴氏:次の項目に進みます。mockやfakeなどテストのときだけ必要なものなど任意のモジュールをimportしたいという需要はあると思います。
KMMの構成です。moduleAというかたちでKMMのプロジェクト側で定義されたときに、iOSKMM.framworkというフレームワークが1個生成されます。
モジュールが複数あった場合は、そのモジュールをまとめるモジュールを1つ用意して、まとめたモジュールをビルドすればiOSのフレームワークとして出力できます。
さらにそこに対してmockなどテストのときにしか使いたくないモジュールを別なモジュールとして定義して、それにアプリ側で使うものを紐づければ、2つのフレームワークとしてKMMのフレームワークとmockのフレームワークを生成できます。
ここで注意しないといけないのが、KMMのmockのフレームワークに対してiOSのもともとのKMMのフレームワークがリンクされていないということです。iOSKMMMockでiOSKMMをimportしている状態にはなっていないです。
実際にフレームワークから見ると、まったく同じものを別モジュールとしてビルドしたものが、それぞれできあがるというかたちです。
なので、例えばApiClientというクラスがmoduleAにそれぞれあったとしても、iOSKMMとiOSKMMMockでは型が別なものという扱いになります。
今回はCocoaPodsを使ってこれを取り込んでいるので、これは妥協案なんですが、iOSのconfigurationのRelease向きかDebug向きかというもので設定ができます。
テストするときには基本的にDebug configurationを利用して、ストアにリリースするときのアプリに対してはRelease configurationを利用します。そのconfigurationで紐づけるフレームワークを変えることで、一応利用できます。
厳密に言うと、テストのときだけ利用したいものをimportするのではなくて、開発のときにだけテストで利用するものも含められるようにするという対策をしています。
この方法じゃなくても、テストターゲットのビルド時にリンクするフレームワークを変更するスクリプトを書けば使えなくはないのですが、そのままCocoaPodsの機能として使っています。
その延長で、実際にKMMのフレームワークをCocoaPodsのプライベートリポジトリのReleasesにアップロードして利用できるようにする方法です。
公式でアナウンスされているものは、native.cocoapodsというプラグインを入れて、Gradleの設定ファイルの中にCocoaPodsの設定を書いて、それらを同一の階層にいるものとみなしてpathで指定して取得するという方法です。
ビルドしたものを都度iOS側で取り込むのではなくて、リンクされたものをスクリプトでビルドしてiOS側で参照します。
今回実現している方法はそうではなくて、Kotlin Multiplatformで生成したものをzipでプライベートリポジトリのReleasesにアップロードをして、Podspecを自分自身で定義して、それをプライベートなSpecsにアップロードして、Xcodeから取り込む場合には、CocoaPodsでPrivate SpecのPodspecを指定して実際の成果物をダウンロードするというものです。
これを通常使うPodspecの定義で定義すると、このようにダウンロードのzipのリンクを定義することになると思います。プライベートリポジトリのReleasesだとWebサイト上はアクセスできるんですが、実際にそのリンクから直接アクセスしようとすると、認証状態だったとしてもそもそもアクセスするURLが違うのでエラーになってしまいます。
なので、すごく長くなっちゃうんですが、さっきの定義していた部分がこの赤い部分だとして、Podspec自体が定義ファイルではなくて実質Rubyのコードを書けるスクリプトになっているので、assetのURLを取得するものを含むかたちにしています。
動きとしてどうなっているかというと、podのrepo pushでプライベートなspecsにpushします。specの中で実際にGitHubのAPIに該当tagの情報を取りに行って、そのReleasesの情報の中から該当するzipファイルの名前を取得して、そのassetのURLを取得してspecのsourceの中に入れるという処理をしています。
これは疑似的な定義ですが、先ほどの長い定義ファイルの中で外側から見えるのはこのsourceで、GitHubのassetsのダウンロード先のURLが取得できます。
そのままアクセスするとzipではなくて、JSONとして定義の情報を取ってくるだけなので、application/octet-streamをheaderで指定して、typeはzipで取ってきます。
Private Specのテンプレート自体はGistで公開されているので、ぜひ見てもらえればと思います。
ちょっと多いんですが、Releasesを利用するときの注意点を簡単に上から話します。pod installのときにspec自体はインストール可能な状態なんですが、lintをかけようとするとvalidationのエラーになるというものがあるので、現在はそれを実行しない方法で対策を取っています。
外部のFacebook SDKでもspecのlintを試してみたらエラーになったので、これはおそらくまだ修正されていない問題なんじゃないかなと思っています。
ダウンロードするときにはGitHubのACCESS_TOKENが必要になんですが、pushのオプションで--use-jsonを使うとACCESS_TOKENが先ほどのJSONファイルに書き込まれてしまうので、netrcを使って認証するのをおすすめします。
また、xcftameworkを使うと実際にリンク可能なものでもpod repo push時に内部で走っているlinkerのテストでエラーになる場合があるので、importのvalidationとtestをskipすることで現状はいったん回避しています。
あとpod installの時に実際にpodでpushしたときもnetrcかGITHUB_ACCESS_TOKENを使っていた場合にはどちらかを利用しなければなりません。ここまでがCocoaPodsの導入の仕方です。
最後に、あまり該当する人はいないとは思いますが、Kotlinで実装されたNSObjectのサブクラスをSwizzleするとクラッシュするという問題があります。
サードパーティのフレームワークなどで、iOSだとSwizzlingという、もともと定義されているメソッドを書き換えるものがあるんですが、それが使われているとクラッシュするということが発生しています。
これはkotlin-nativeの1.4.30では直ってはいるので、バージョン的に使えないという方向けに説明します。参考の実装として、APIを通信する部分でktorというものを使っています。
ktorにはIosResponseReaderというものが実装されていて、それがNSObjectのサブクラス、かつURLのDelegateを実装しています。
Delegateのメソッドがこのようなかたちで4つほど定義されています。このメソッドがパフォーマンス計測などでSwizzlingされることがあります。
これらがIosClientEngineというもので実際にktorの中で定義されているんですが、iOSのNSURLSessionをKotlin側で初期化されたときにresponseReaderをDelegateとして渡す状態で使われています。
responseReader自体がinternalで定義してあるので、なにか修正を加える場合にはforkして対応するか、そのままコピーして修正を加えるかの方法でしか対策は取れなくなります。
今回の例に関しては、Swift側でURLSessionのinitializer自体をswizzleできれば、Kotlin側のサブクラスをswizzleすることにはならないので、delegate自体を入れ替えます。
swizzleをして、クラスの名前がKotlinに関連しているktorのものだったら入れ替えをして、1個ラップしたdelegateで実装します。
delegateの実際の内容は、先ほど定義したdelegateメソッドをもう1度Swiftで定義し直して、実際にKotlinに定義されているものを1個ラップして、愚直にメソッドをもう1度呼び直すというものです。
直接Kotlin側で定義されたNSObjectのswizzleが走るわけではないので、クラッシュを回避できます。これはiOSのswizzleするときのメソッドです。
私からはiOSに導入する部分でいろいろと話をしました。ご清聴ありがとうございました。
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
2024.12.11
大企業への転職前に感じた、「なんか違うかも」の違和感の正体 「親が喜ぶ」「モテそう」ではない、自分の判断基準を持つカギ
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦