2023年2月1日水曜日

[Xcode Organizer] ipaファイルをexportできない

【問題】

Xcode OrganizerでArchivesを選び「Distribute App」するとエラーが出る

次出るはずの画面はApp Thining(下図)なのだが、エラーになるということは、おそらくプルダウンメニューを作るために走らせているrubyのスクリプトが、途中でコケている模様。

なお残念ながら「Show Logs」を押しても、足がかりとなる情報は何も得られない。


【手がかり】

「/usr/bin/gem list」のコマンドが、正しく動作しないことに気がついた。


【背景】

cocoapodsを入れるために、Rossetaモードで試みたり、brewで導入したりと、環境を悪くしたことに原因があると思われる。


【対処】

「sudo /usr/bin/gem update --system」で、gemの更新を実行(3.0.3.1→3.4.2)。
エラーとなったので、Rossetaモードで実行し直した。
「/usr/bin/gem list」は動くようになり、「Distribute App」は成功するようになった。

【解決までの過程】

Xcodeは、プリインストールされたrubyを使っていると思われる。

brewによる導入のためgemが2つ存在(where gemで確認できる)し、brew側が優先されている(which gemで確認できる)場合に、優先されていないプリインストールされた「/usr/bin/gem」側で実行しようとして、失敗しているようだった。

上手くいっている別環境と比べると、「/usr/bin/gem env」で見えるパスに「/usr/bin/〜」が混ざっている点に気がついた。

ここを直せば治りそうなものだが、設定を直す方法がさっぱりわからず、試行錯誤していたところ「ver.3.0.3.xのgemはupdateすべき」というメッセージが出てきたので、試しに3.4.xに更新したら解決した。

改めてenvしてみると「/usr/bin/〜」が

「/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/〜」

に置き換わっていた。

2023年1月22日日曜日

[Xcode] 古いXcodeを使う方法

libstdc++を要求するモジュールをビルドしたいのだが、


の方法でlibstdc++を導入しても、ビルドできるのは、Xcode 13.2.1が最後。


でXcode自体は入手できるが、


というマークとなり、起動すると「最新版を取得せよ」と意地悪される。
この問題を解決したい。


【命題】


古いXcodeでビルドしたい。


【解決策】


ターミナルで、

#!/bin/zsh

/Applications/Xcode_13.2.1.app/Contents/MacOS/Xcode



というスクリプトを書き、例えば「Xcode13.command」という名で保存する。


【使い方】


このコマンドをダブルクリックすると、Xcode13.2.1が立ち上がる。
ただしターミナルは開きっぱなしになる。

Xcode終了時に自動的に閉じるようにするには、以下のようにする。



【残念ながら】


ここまで頑張っても、App Storeへの提出要件が、Xcode14になるとリリースできなくなる。

Xcode13.2.1でしか生成できないものはライブラリとしてFIXしてしまい、Xcode14で改めて外部リソースとして引き込むように、プロジェクトを見直せばいいのかな?

2022年11月21日月曜日

[Xcode, CocoaPods] VenturaでCocoaPodが動作しなくなった


1. 問題点


macOS 13 Venturaにアップデートして、pod --versionとしただけで、

Ignoring ffi-1.15.5 because its extensions are not built. Try: gem pristine ffi --version 1.15.5

Ignoring ffi-1.15.4 because its extensions are not built. Try: gem pristine ffi --version 1.15.4


こんなのがたくさん出るようになった。


2. 処方箋


1. Command Line Tools for Xcode X.Xを忘れずに。

2. Rossetaチェックを入れてターミナルを起動。uname -mでx86_64であることを確認しておくこと。

3. gem listでcocoapodsがあることを確認。入れてない人はsudo gem install cocoapods
 →gemがない人は論外。which gemでプリインストール/usr/bin/gemを確認できるはず。

4. 以下を実行
sudo gem install ffi --version 1.15.4
sudo gem install ffi --version 1.15.5

3. 結果


pod --versionとしても、エラーなくバージョンが表示される。
pod installやpod updateも、正しく動作する。

4. うまくいかない場合


ruby -v →2.6.10、gem -v →3.0.3.1の場合はうまくいったが、別に所有するgem -v →3.3.11の環境では、にっちもさっちも行かなかった。

dolphinicityさんのやり方に従ったところ、成功しました。
→ありがとうございます。


5. 追記


だんだん混乱してきたので、頭の中を整理するために記録しておく。


・そもそもの問題点

Venturaに含まれているruby/gemでは、cocoapodsはインストールできない。

→解決法

brewでrubyをインストールする。


・既に/usr/localにbrew導入済だと以下のエラーが出る

Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)!

Please create a new installation in /opt/homebrew using one of the

"Alternative Installs" from:

  https://docs.brew.sh/Installation


→解決法は以下のどちらか

・brewを/opt/homebrewに入れ直す。
・brewを使う時は、我慢していちいちRossetaでターミナルを起動する。

2022年7月18日月曜日

[Xcode13.3] 非消耗型アプリ内課金コンテンツのホスティングサービスの終了


序文


Appleから2月頃以下のようなメールがきた。普段はすぐ捨てるが、なんか引っかかるところがあったので、捨てないで置いておいた。

Title: Upcoming changes to hosting non-consumable in-app purchases.

We’re reaching out to let you know about upcoming changes to in-app purchase content hosting. In Xcode 13.3, we’ve removed the option to upload non-consumable in-app purchase assets for Apple to host. In addition, support for managing these assets in App Store Connect will be removed starting in April 2022.

Existing assets hosted by Apple won’t be affected and you’ll still be able to manage their associated in-app purchase details, such as pricing and availability, in App Store Connect.

Moving forward, we recommend taking advantage of on-demand resources to host in-app purchase assets on the App Store, separately from the app bundle. You can enable smaller app bundles, faster downloads, and richer content.

最近久々に、アプリの更新をしてみたところ、このお知らせの意味する重大な問題にやっと気づいたので、これを解説したい。

何ができなくなるのか


私がリリースしている「学区ビューア」というアプリでは、GIS情報がデカすぎる等の理由から、アプリに内包(バンドル)せず、後からダウンロードできるようにしている。
今まではApple Store Connectを利用して、Appleが用意したサーバーにアップロードできていたわけだが、どうもこのサービスをやめたいらしい。
正確には、新規登録は受け付けない、既存の更新は許すが、アップロードしたいなら13.2以前のXcodeを使うか、別な手段(コマンドライン)でやりなさいということらしい。

私の例でいうとXcode13.2では、


のような画面を拝めたが、13.3以降では機能がなくなったので、プロジェクトをロードした時点でエラーとなる。

代替手段はあるのか


Apple Developer Forums
で議論されている。

Appleの中の人は、ODR(オンデマンドリソース)とやらを利用せよというが、


ODRは概念であって、非消耗型アプリ内課金コンテンツに対して、新しい置き場所が用意されたわけではないようだ。
実際、ODRのドキュメントには「Cloud or Apple Store」と記載されており、今後Apple Storeを利用できないとなると、Cloudしか残らない。
そしてCloudとは何かというと、要は自分でサーバーを用意せいっということらしい。
少なくとも私はそう読み取った。

外部サーバーへの接続、外部コンテンツの取得は、初期の頃はガイドライン的にNGだったはずだが、大手デベロッパーから押されてAppleも徐々に方針転換。
大手は大歓迎だろうが、個人が証明書類が揃ったサーバーを用意してまで、アプリのコンテンツを配信するのかと問われると、それは厳しいとしか言いようがない。

2020年9月30日水曜日

[Visual Studio] Xamarinセットアップ

1.Android,Windows,iOSのクロスコンパイルができてしまう⁉


Visual Studio 2017/2019には、Microsoftが買収したXamarinが入っており、Android、Windows、iOSのクロスコンパイルができてしまうという、夢のような仕組みがあるらしい。
このうちiOSについては、そんなにうまい話ではないことが、露見した。
どうも、Visual Studio for Macを入れたMacが必要で、WindowsのVisual Studioと連携するらしい。
実行ファイルの生成、実行ファイルの実行はMac側で行われ、Windowsは単に窓口ということらしい。
なんかかえって面倒なことに巻き込まれそうなので、iOSはあきらめた。

今回の目的は、既にiOSで動いているアプリを、Androidに移植することであり、どうせならWindows版も同時に作れたらいいなぁぐらいの感じだったので、Android Studioではなく、このXamarinで開発することに決めた。


2.UWPというプロレス団体


さすがにMFCはもう使っていないが、いつもWindowsアプリは、.Net Framework+C#で作成し、Windows Formsアプリとしてリリースしている。
WPFとかStoreアプリという選択肢は見たことがあるが使ったことはなく、UWPという新しいプロレス団体のようなものについては、知る由もない。
とにかくXamarinを使うなら、この団体に加入しないといけないらしい。UIはXAMLで記述しないといけないらしい。


3.「Android SDKとツール」が真っ白


とりあえずMicrosoftのいう通りやってみた。

ビルドは通り、Androidのエミュレータも起動するが、サンプルが実行されない。
なんかよくわからないけど、バージョンが古いとか、Hyper-V使った方がいいとか言われ、「Android SDKとツール」ダイアログに誘導される。
が真っ白で何もでてこなくて困惑。

【処方箋】
歯車マークから、リポジトリをMicrosoft(推奨)→Google(サポート対象外)に変更すると治った。


4.Hyper-Vの有効化


Microsoft様の説明

結論からいうと、Windowsの機能で、Hyper-VをONにすればいい。
しかし、BIOSでVirtualization Technology (VT-X)が無効になっていると、Hyper-Vプラットフォームのチェックボックスがグレーアウトで触れない。


その場合は、BIOSでの設定変更が必要(いまどきの64bit Windows PCのBIOSなら選択肢があるはず)。


5.管理者権限でVisual Studioをつかう


「選択したエミュレーターを起動できませんでした。これはプロセスに十分なアクセス許可がないことが考えられます。VS を管理者として起動すると回避できる可能性があります。」
といわれる。常に管理者権限でないとダメなの?


6.UWPでビルドできない⁉


ソリューションエクスプローラにUWPが出てくるが、移行が必要とか言われる。
そもそも、新規プロジェクト>Cross-Platformで、UWPのチェックボックスが触れない。


Visual Studio InstallerでUWPを全部入れたら治った。


7.XAMLデザイナーって使えないんすか(゚Д゚)ハァ?


どうやって画面作ったらいいんでしょう? しばし茫然。
プレビューはあるらしいのだが、メニューに見当たらない。どこにあるのやら。

よ~く見ると右下に左右分割という小さなボタンがあり、これを押すとXAMLのプレビュー画面がでる。



2020年7月18日土曜日

[App Store Connect] App Storeに掲載する動画(Appプレビュー)をつくる

1. 実機がある場合


iOS12からいいものが実装された。録画ボタンを押すだけ!


あらかじめ15〜30秒以内に編集しておくと楽。

しかし最近の機種は、FPSが30以上になってしまう。
「設定>カメラ>ビデオ撮影」では、スクリーンキャプチャのFPSは制御できない模様。

FPSは30以下にしないとApp Storeにアップロードできないようなので、例えばffmpegで変更する。

コマンド例)ffmpeg -i in.mp4 -r 30 out.mp4


CUIが嫌な人は、下記のiMoveを使ってもいい。


2. 実機がないので、Simulatorを録画する場合


1. QuickTime Playerの「新規画面収録」を使う。


なんか知らないが、キャプチャーサイズは1/2スケールでいいようだ。
iPad用の1200×1600なら、600×800。
【ハマりPoint】収録終わりのボタンは、なぜかメニューバーにある。


2. QuickTime Playerが吐き出したmp4ファイルを、iMovieで編集。



「新規アプリケーションプレビュー」で編集する。

とにかく最終的に共有メニューから「アプリケーションプレビュー」(赤丸)を選びたいので、そうなるように頑張る。
なお、下段の編集タイムライン上をハイライトさせないと、赤丸は出現しない。


【ハマりPoint】このままだと無音なので、音を追加。

無音だとApp Storeにアップロードできない。
瞬間でもいいので、音声(紫丸)を追加すること。


3. iMovieの代わりにKeynote


以前Keynoteでもやったことがあるので、備忘録として記載する。

1. ドキュメントサイズを所望のサイズに設定
2. その上にmp4ファイルを載せる
3. ムービーで書き出す。元ファイルの前2秒、後5秒に静止画が追加される模様。



2020年6月6日土曜日

[iOS13, Xcode11, ShareExtension, 共有] 「〜で開く」ではなく「〜にコピー」にしたい。

1. 共有には2種類ある


自分で実装するまであまり考えたことがなかったのだが、共有には「Clipbox+」と「"Clipbox+"で開く」のように、「で開く」が付かない物と付く物の2種類がある。
そして動きが違う。
赤丸は編集モードのようなものが開くが、青丸はアプリ(ここではClipbox+)に遷移する。


2. Share Extensionを使った方法


赤丸はShare Extensionを実装すると出てくるようになる。
こちらのページが詳しい。

何をしないといけないかというと、Share Extension機能をもった別のBundle ID(例えばClipbox.shareとか)を持つ、新しいアプリを作らないといけない。

この新しく作ったアプリのinfo.plist内NSExtensionActivationRuleで、サポートしている機能を記述することにより、iOSに自分が持つ機能を宣言することになる。
結果、共有ボタンを押した時にiOSが、候補(Suggestions)に、新しく作ったアプリのCFBundleDisplayNameを表示できるようになる。

候補から新しく作ったアプリを押下すると、新しく作ったアプリがキックされ、標準で用意されているPostを押下すると、didSelectPost()でURL名、ファイル名、文字列等が獲得できる。

獲得したものを元のアプリに渡せば一件落着のはずなのだが、実は、新しく作ったアプリと、元のアプリは別のものなので、直接データのやりとりはできない。

この障壁を回避するために、App Groupsと言われる共有空間が用意されている。
新しく作ったアプリと、元のアプリで同じApp Groupsを定義して使う。
Xcode上で実施すればうまくいくはずなのだが、うまく自動生成できない場合は、Apple Developper Program「Certificates, Identifiers & Profiles」のページで手動登録するしかない。

作成した共有空間にデータを書き出す方法としては、ググると、plistでの方法が、

let userDefaults = UserDefaults(suiteName: "group.XXX.XXX")
userDefaults.set(item, forKey: "text")
userDefaults.synchronize()


紹介されているが、後々のことを考えると、ファイルやりとりの方が便利と思う。

let dst = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.XXX.XXX")?.appendingPathComponent("test.txt")
item.write(to: dst, atomically: true, encoding: .utf8)

3. Share Extension :アプリをキックできない


ここまで頑張って実装しても、コード上から元アプリを呼び出すことができないので、元アプリをユーザーが立ち上げなくてはならず格好が悪い。
iOSの仕様変更で今はできない。昔はできていただけに情けない(こちらに詳しい)。

でもAdobeはできてるんだよね。何か方法はあるのだろう。


4. Document Content Type UTIを使った方法


表題の「〜で開く」「〜にコピー」の話だが、Windowsで言うところの拡張子の関連付けみたいなものだろうか、UTIで設定すればいいだけ。
Share Extensionに比べると相当楽。

ただ以下の点でつまづいた。
・public.textを指定しても、標準アプリの「メモ」からは呼び出せない。
・「〜にコピー」にしたいのに、「〜で開く」になってしまう。

それぞれの処方箋は以下のとおり。
【処方箋】標準アプリの「メモ」はそもそもUTIが謎。あきらめてShare Extensionの方法で対応した。

【処方箋】「〜で開く」は、LSSupportsOpeningDocumentsInPlaceを削除すると「〜にコピー」にできる。(*1
iOSは、LSSupportsOpeningDocumentsInPlace=NOが必要。(*2
MacOSは、LSSupportsOpeningDocumentsInPlaceは削除。(*3

*1 以前は、ApplicationDelegateで受け取るために、LSSupportsOpeningDocumentsInPlaceが必要だったが、今は常にSceneDelegateが呼ばれる仕様に変わったようなので、削除することができる。

*2 iOSアプリをAppStoreにあげる時、LSSupportsOpeningDocumentsInPlaceがないと、Document Typeを指定してるくせにと怒られる。

*3 一方でMacOSアプリでは、LSSupportsOpeningDocumentsInPlace=NOは許されないので、削除するしかない。


5. ShareExtention:public.textだけどpublic-file-urlもサポートすべき例


public.text系のアプリから、青丸の「〜でコピー」を選択すればうまくいくのだが、試しに赤丸のShare Extensionも試してみると、UTTypeText(public-text)が空っぽだった。

しかし、kUTTypeFileURL(public-file-url)には、ファイルパスが入っていたので、どうやらこれを使えということらしい。
標準の「メッセージ」や「メール」は、当然のことながら、うまく実装できていた(下図)。