コベリンの最近の取り組みとして、業務などで役立ちそうな知見を共有する会を開催することになりました。 そのついでに発表に使ったアジェンダもそのまま公開してしまおうという豪快な企画です。
※ アジェンダをそのままコピペして公開したものなので若干見にくい箇所もあるかもしれませんが、ご了承ください。
- Apple Silicon(M1) の mac だと Share Extension がうまく動かなかったお話 @mironal
- Run ScriptのPATHにhomebrewのパスが入って来なくなった @takkumattsu
Apple Silicon(M1) の mac だと Share Extension がうまく動かなかったお話 @mironal
概要
Share Extension のときに使う NSItemProvider
の hasItemConformingToTypeIdentifier(_ typeIdentifier: String) -> Bool
がどうやら正しい値を返さない
M1 mac の iOS シミュレーター(Xcode 12.4, Xcode 13の両方)でのみ現象を確認しており、 Intel mac でのシミュレーターや実機ではこの現象は発生しなかった。
不具合の調査に何時間もハマって悲しかった。
詳細
Apple 製品はファイルの種類の識別に Uniform Type Identifier
というものを使います。
Share Extension は様々なアプリから様々な形式でデータが渡されるため、データ形式から処理を分岐することがある。 例えば動画・画像、画像と言っても jpeg なのか? png なのか?など。
そしてそのファイルの種類の検出に使えるメソッドの一つに NSItemProvider
の hasItemConformingToTypeIdentifier(_ typeIdentifier: String) -> Bool
がある。
NSItemProvider
とは Share Extension に渡されたデータの情報が入っているクラスである。例えば一つの URL を共有した場合には、その URL の情報が入った NSItemProvider
が一つだけ入手できる。複数の画像を選んで共有した場合にはその数だけ NSItemProvider
が渡されるという感じである。
例えば Share Extension の中で渡されたデータが画像だった場合に、何かの処理をしたいときは以下のように書く。
guard let inputItem = extensionContext?.inputItems.first as? NSExtensionItem else { fatalError() } // attachment が NSItemProvider である guard let attachment = inputItem.attachments?.first else { fatalError() } if attachment.hasItemConformingToTypeIdentifier(UTType.image.identifier) { print("画像だった場合の処理") } else { print("画像じゃない場合の処理") }
このコードを含む Share Extension を実行して、Photosアプリ(写真アプリ)から適当に画像を一つ選んで 開くと、常に 画像じゃない場合の処理
のログが出てしまいます。
つまり attachment.hasItemConformingToTypeIdentifier(UTType.image.identifier)
が false を返してしまいます。
細かい動作確認
デバッグのために以下のようなコードを書いて走らせました。
print(attachmentItem.registeredTypeIdentifiers) print("Is jpeg", attachmentItem.hasItemConformingToTypeIdentifier(UTType.jpeg.identifier)) print("Is image", attachmentItem.hasItemConformingToTypeIdentifier(UTType.image.identifier))
jpeg の画像を開いた場合は 以下のようなログが出ることを期待しています.
- ["public.jpeg"]
- Is jpeg true
- Is image true
実機で実行
実機で実行した結果が以下になります。
["public.jpeg"] Is jpeg true Is image true
納得です。
M1 mac のシミュレーターで実行
以下のようになりました。
["public.jpeg"] Is jpeg true Is image false
jpeg なのに image じゃないとはどういうことなのか...?
さらなる調査
単純に UTType
の処理が壊れているのかな?と推測して以下の処理を実行してみました。 jpeg は image を conform しているので true が得られるはずです。
print(UTType.jpeg.conforms(to: .image))
実機
true が得られました。
M1 mac のシミュレーター
false が得られました。
また以下のようなログが出力されていました。
Failed to realize static UTType instance 0x10e1c60b0 for identifier public.jpeg. Please file a bug. The type should be present in Core Types.
なにか特有の問題があるようですね...
まとめ
めちゃくちゃわかりにくい不具合なので注意してください。
Run ScriptのPATHにhomebrewのパスが入って来なくなった @takkumattsu
背景
ちょっと特殊なプロジェクトでiOSとAndroidの共通処理をC++で書いているプロジェクトがあり、C++部分の開発はXcodeやることが多かったので Run Script に clang-format
を走らせるスクリプトを入れていた
現象
Xcode13 or m1 Mac にしてからhomebrewで入れていたclang-format
がスクリプトから見えないという現象が起きいてた
実際にRun Scriptに設定していたのはこんな感じ
一部プロジェクト名の部分はぼかしています
#!/bin/sh SCRIPT_DIR=$(cd $(dirname $0); pwd) cd $SCRIPT_DIR/.. COMMON_DIR="${SCRIPT_DIR}/../common" COMMONS=$(find $COMMON_DIR -follow -type f | egrep ".h$|.hpp$|.cpp$") for f in $COMMONS do clang-format -i $f done OBJC_DIR="${SCRIPT_DIR}/../プロジェクト名" OBJS=$(find プロジェクト名 -type f | egrep ".m$|.mm$|.h$") for f in $OBJS do clang-format -i $f done
解決策
解決策は単純にパスを通しただけ
diff --git a/ios/tools/wrapper_format.sh b/ios/tools/wrapper_format.sh index a305b309..c68f2754 100755 --- a/ios/tools/wrapper_format.sh +++ b/ios/tools/wrapper_format.sh @@ -1,5 +1,9 @@ #!/bin/sh +if [ -d /opt/homebrew/bin/ ]; then + export PATH=/opt/homebrew/bin:$PATH +fi + SCRIPT_DIR=$(cd $(dirname $0); pwd) cd $SCRIPT_DIR/..
原因はちょっとわかってない
m1 MacにしたタイミングなのかXcode13にしたタイミングなのか分かってないですが環境を変えたタイミングで起きました。 普通に考えるとパス通してないので以前の環境でも起きておかしくなさそうな気もする?
完全に関係ない話
Uber Eats で天下一品があったので注文してみた。 自分で麺を茹でることもできこういうタイプはかなりお店の味に近づけるので期待度が高かったが、食べてみた感想はそこまでだった。 こってりを頼んだのだがお店のあのこってり感は再現できなかった。 今のところラーメンだと町田家のUberEatsが店の味に近かった気がしました(おわり)