Mac Catalyst Hacking ~macOSでHomeKitアプリを開発するために

3.8K Views

May 15, 22

スライド概要

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

#macOS native Mac Catalyst Hacking ~macOSでHomeKitアプリを開発するために Yuichi Yoshida © 2022 Yuichi Yoshida. All rights reserved. Redistribution or public display not permitted without written permission from Yuichi Yoshida.

2.

自己紹介 • sonson • 昔,2tchという2ちゃんビューアを作ってた. • iOSの本も書いてたけど,今は昔・・・・ • 本業は,画像認識とか,機械学習とか,そういうの

3.

HomeConMenuをどぞ Mac App Storeで公開中 ソースコードも公開中 https://github.com/sonsongithub/HomeConMenu

4.

ことの発端 • なんでmacからHomeKitデバイスの操作がこんなにやりにくいのか iOSはまだマシ.2stepでオン・オフできる アプリをわざわざ起動して・・ウィンドウもでかい

5.

macOSアプリで作ったろ HomeKitがない・・・?だと・・・? Home.appは,Appleがズルしてるってことか!!!!!!!

6.

HomeKit.frameworkはCatalyst専用 • HomeKitは,iOS/iPad OSのみだが,Mac Catalystなら使える • おっしゃ!!!Mac Catalystやったら使ったことある!!! • これで,メニューバー常駐でデバイス操作するの作ろうっと! しゅーりょー

7.

bundleによるCatalystの改善 なんとしても,AppKitにCatalystからアクセスしたい 1. Dynamicというライブラリを使う 1. 2. Private APIにアクセスしやすくするやつ Bundleを使う 1. macOSのみでビルドされたバイナリをCatalystのバイナリにバンドルとして付属させる 2. 実行時にmacOSのみでBundleをロードし,使う https://betterprogramming.pub/how-to-access-the-appkit-api-from-mac-catalyst-apps-2184527020b5

8.

どっち? Dynamic Bundle 怪しいプライベートAPIを辿ってアクセス レビューア(ヤクザ)にいちゃもんつけられる 後ろ指刺されることはない・・・はず 正規のルート!!のはず 🤔 😀 https://betterprogramming.pub/how-to-access-the-appkit-api-from-mac-catalyst-apps-2184527020b5

9.

誤解を恐れないイメージ Catalystバイナリ UIKit/Mac Catalyst HomeKit AppKit/Cocoa(本当?)

10.

誤解を恐れないイメージ Catalystバイナリ Bundle UIKit/Mac Catalyst HomeKit AppKit/Cocoa(本当?)

11.

誤解を恐れないイメージ Catalystバイナリ Bundle UIKit/Mac Catalyst HomeKit AppKit/Cocoa(本当?) macOSのみをターゲットにして実装する

12.

誤解を恐れないイメージ Catalystバイナリ 実行時にロード Bundle UIKit/Mac Catalyst HomeKit AppKit/Cocoa(本当?)

13.

誤解を恐れないイメージ UIKitとMac Catalystしか話せない やりとりはお互いの環境に共通する型 Obj-Cで使える型 Anyなどで通信 Bundle Catalystバイナリ UIKit/Mac Catalyst HomeKit AppKit/Cocoa(本当?) AppKit/Cocoaしか話せない

14.

イメージ UIKit HomeKit APIを叩くなど Mac Catalyst iOSController mac2ios Protocol 参照 Bundle MacOSController iOS2Mac Protocol こいつは実行時にロード AppKit/Cocoa NSMenuを作るなど

15.

iOSの新規プロジェクト

16.

Mac Catalystをオン

17.

macOS BundleをTargetに追加

18.

適当に名前をつける

19.

Principle classをセットする

20.

macOS BundleをCatalystでインポートする

21.

BundleとCatalystの境界 やりとりするクラスは NSObjectProtocoloに準拠しないとダメ BundleとCatalystの境界を結ぶプロトコルなので,元のCatalyst, Bundleの両方のターゲットに追加する. ここには,StringやUUIDなどのAppKitでも,UIKitでも共通して含まれる型しか宣言できない.

22.

いよいよBundle本体を作る 名前は,MacControllerとかにした Obj-Cの仕組みを使うので,bridging headerを追加しとく

23.

ここではCocoaが使える ターゲットは,Bundleだけに追加. ここでは,自由にAppKit, Cocoaが使える.Catalyst側から呼び出したい処理を関数で実装しておく.

24.

Catalyst側からロードする 複数クラスがあったり,Principal Classが間違っていたりすると ここで失敗する.ちゃんと確認すること.

25.

Catalyst側から呼び出せる

26.

うまくいかないとき • • コンパイル • プロトコルのUIKitとAppKitの変数がごっちゃになってる • 使えないクラス,型を使っている 実行時 • Bundleからクラスをロードするときに型を間違ってる • デバッガでちゃんと型通りのものがロードされているか確認

27.

必要な工夫 • String, Int, Anyみたいなものしか渡せない • AnyにしてBundle側に持たせるとかはできる • Optionalは渡せないが,例外は飛ばせる • asyncのメソッドは,リンカがコケる.なぜ? • #if !os(macOS)で処理の切り分けは可能 • HomeKitは,すべてにUUIDが振られていたので,実装しやすかった • “Application is agent (UIElement)”などがInfo.plistで指定できたりした • SwiftUIをAppKit側に渡せないかと画策してみたがダメだった・・・・・

28.

その他の問題 • 署名関連 • HomeKitを使うMac Cataslytのアプリは,notarizeできないし,署名もできないので,配布できない • • • 無署名は配布できるが,署名のないアプリはHomeKitにアクセスできない・・・・ HomeKitを使うMac Cataslytのアプリは,Mac App Storeでしか配布できない Mac App Storeのアイコン • Catalystでデフォルトのアイコンアセットを使うとMac App Storeのアプリアイコンがおかしくなる • Macアプリのアイコンアセットを作り直し,それをアプリアイコンにセットする必要がある • iOSベースの奴は何か問題がある・・・・?

29.

まとめ • macOSでHomeKitアプリを作るために • Mac CatalystでもAppKit/Cocoaは触れる • DynamicライブラリとBundleの二つがある • Bundleアプローチが楽だけど,インタフェースが大変 • optionalが渡せないので,(あれ?nullableとかなかったっけ?)例外でやるとよい • macOSでHomeKitを使うアプリは,Mac App Storedでしか配布できない