Cycling'74の"Max"(Max/MSP)でプログラミングして、MacAppStoreでアプリを販売する方法
今回はかなり専門的な内容です。Macのスタンダードアプリケーションは、ビジュアルプログラミングの"Max"を使っても出来るという話。
かなりニッチな話題なので、このnoteにどれだけニーズがあるか分かりませんが、自分自身への健忘録としての意味も含めて、ここに記載しておこうと思います。
自分の作ったアプリケーションを配布する方法は色々ありますが、最近セキュリティの敷居が高くなってるMacの場合は、実行ファイルをネット上で配布する方法は限定されます。
Macユーザーにとっては、MacAppStoreで販売、配布されることは信頼性が高く、最も有効な方法だと思います。
現在私がMacAppStoreで、リリースしているアプリは4つあります。いずれも2013年から2014年に制作したもので、リリース後長い期間アップデートしなかった為に、OSのアップデートと共にレギュレーションも変わり、利用できなくなっていました。
それを2020年暮れに、一斉にアップデートしました。
"Max"のStandAlone Appを、MacAppStoreにアップするために必要なもの。
まず前提条件として必要なもの、"Apple Developer Program"に加入することと、独自の"Identifiers"を持つために、ドメインを取得する必要があります。
"Max"でビルドするしないに関わらず、この二つは必須になります。
"Certificates, Identifiers & Profiles"の設定は、Xcodeで作るアプリケーションと変わりません。また、これらの作業は実際にアプリをリリースする時点で必要になるもので、かつ費用が掛かるものです。
取得するのは一番最後で構わないと思います。
もちろん、Cycling'74の"Max"の正式版を購入することも必須です。
プログラミングとビルドで必須の項目
まず最初に、Cycling'74のオフィシャルサイトで説明されている、【Part2】の項目を読んで欲しい。その上で少し補足していきます。
Presentationモードで動くこと。
当然ユーザーインターフェースは、プレゼンテーションモードの画面を使います。ビルドする"Window"の"Inspector"の、"Open in Presentation"にチェックを入れておく必要があります。
UIをデザインするのは、"Max"の既存のUIがそのまま使えるので比較的簡単ですが、インターフェイスから"Max"ぽさをなくそうとすると、そこが非常に難しかったりします。
menubar(メニューバー)の制御
ここからは実際、Maxのpatchに必ず組み込む必要のあるオブジェクトを解説していきます。
まず第一に、画面のトップに表示される、メニューバー(menubar)です。
Appleのアプリの仕様上、メニューバーが正常に動作する必要があります。仮にメニューを必要としないアプリであっても、トップに表示される、"~について"("About ~")は必ず必要です。
さらに、"ファイル"("File")のメニューに登場する。"Open","Close","Save","Save as"などは、メニュー項目から消すことが出来ません。Appleの審査を通すために、これらが何かしら動作する様に作っておく必要があるようです。
ただし、動作自体に有用性は無くても構わないようですので、私は単純に、"buffer~"にオーディオデータの読み込みと書き出しを出来る機能を付けました。(その動作には何の意味も無くても良いようです。)
追加したい項目がある場合、メニューの項目名は、"menubar"をダブルクリックするとエディットする事が可能です。
追加は出来ますが、デフォルトの項目を書き換えることは出来ない様です。エディット方法には、MaxのTutrialに出てきます。
windowの制御(thispatcher)
ビルドするアプリのWindowのサイズを固定化する必要があるので、"thispatcher"オブジェクトに "window flags ~"の設定をしますが、一度設定すると、追加でエディットする際に不都合です。同時にそれらを解除する"Massage"も用意します。
standaloneオブジェクト
こちらは、前述のオフィシャルの記述を参考にしてください。
- update "Bundle Identifier" to match your Apple App ID (com.website.appname)
<ここでも取得した独自のドメイン名が必要になりますし、先にApple Developer Siteで、"Identifiers"と同じ名前にする必要があります。
- update "Preferences File Name"
<プリファレンスファイルの名前を独自の名前にします。
- Can't Close Toplevel Patchers [ ]
- Disable Loadbang Defeating [X]
- Status Window Visible at Startup [ ]
<後は言われるがままで。
さらに、"GEN"や"CEF"(パケット通信)、などを使っていなければ、これらのチェックは外しておいた方が良いです。"Include C74 Resources"は、主にMaxのオリジナルのインターフェイスを指しているのだと思いますが、実際にはチェックを外しても、代表的なUIには影響ありませんでした。
一部、波形の画像を使ったUI(.svg)が表示されなくなる不都合がありましたが、必要なファイルだけをビルドの際にincludeする事で解決しました。
MacOs Application icon(アイコン)の準備も、この段階で必要になります。
アイコンもちゃんと用意されていないと、MacAppStoreの審査の際にリジェクトされてしまうので重要です。icnsファイルの作成は、検索するとでてくるので、そちらを参考に。
windowを閉じたときのアプリ終了の処理
これもAppleの仕様で、Windowが閉じられた際に、アプリも終了するようにする必要があります。
ただ、開発中に面倒なのが、このオブジェクトを作ってしまうと、Windowを閉じる度にMaxも強制的に終了してしまうので、objectを組み込む際は注意が必要です。
Build Collective / Application
以下、私がビルドの際にincludeしたファイルです。
open thispatcher
include ~/Max/GraphArp3v2019/channel_plug2.maxpat
include ~/Max/GraphArp3v2019/graph_mode_vst3.maxpat
include ~/Max/GraphArp3v2019/numTOnote.txt
include ~/Max/GraphArp3v2019/scale_live.txt
appicon ~/Max/GraphArp3v2019/ga_icon.icns
複数のpatchを使っているプログラムも同様で、使っているファイル(サブパッチや、Textファイル)はビルドの際に全てincludeする必要があります。
"appicon"は、アイコンを指定して組み込んでいます。"standalone"オブジェクトで指定しているので、本来なら必要ないかと思いますが、上手く行かなかった事があったので、念のためにこうしています。
さらに、オリジナルの画像ををインターフェイスに組み込む場合は、ビルドの際にそのファイルをincludeする必要があります。
ビルド後の作業
こちらも、まずは、オフィシャルのドキュメントの【Part.3】に目を通してから読んで欲しいのですが、、。
ビルド後の作業は、手順が多くかなり面倒な上に、間違えるとやり直しが大変です。実際私自身も、正しいやり方を見つけるまで本当に四苦八苦しました。
ただ一度理解してしまうと、後は面倒ですが、シンプルな作業の繰り返しになります。
まず、Maxで作ったアプリケーションの構造について、少し理解しておく必要があります。
ビルドされたアプリケーションを右クリックすると、「パッケージの内容を見る」という項目が出ますので、それを選んでアプリケーションの中を表示します。
info.plistの書き換え
この中にある、Contents/info.plistを書き換えて行きます。これも先に挙げたオフィシャルのページを参考にしてください。ちなみに、"info.plist"を書き換えて、"codesign"が終わるまでは、アプリは正常には動作しなくなりますので、書き換え中にアプリが動かなくても心配はいりません。
Update existing rows:
- Get Info string
- Icon file
- Bundle identifier
- CFBundleLongVersionString
- Bundle versions string, short
- Bundle version
Add new rows:
- Application Category
- Minimum system version
ここに挙げた項目はオフィシャルに書いてある項目ですが、これ以外に必要なものがありました。一つは、"Localizations"という項目で、新たに追加して、"English"と"Japanese"の項目を加えました。
これは、OSに由来したダイアログなどが表示される場合に、OSの言語に沿った表示がされるようにするためです。
追加しないと、日本語でビルドした場合、英語OSで起動しても、ダイアログは日本語で表示されてしまうようです。
さらにもう一つに、"Document types"の全ての"item"に"Handler rank"を追加して、"Ower"にする必要がありました。おそらく、このアプリが扱えるDocument Typeのアクセス権に関する項目なのですが、僕も正確には理解していません。ですから、必要なタイプのみの設定でも良いのかもしれません。
不要なファイルの削除
Maxでビルドをすると、必要なMaxのオブジェクトのみをアプリの中に組み込んでくれますが、幾つかのファイルは使っていなくても必ず組み込まれてしまうようです。
MacAppStoreの審査を通す上でも未使用のオブジェクトは、アプリの中から削除します。
At this point, I removed the following files. They caused issues with submission, and my app worked fine without these files. (this is one thing, i’d love to figure out for an updated guide)
/Contents/Frameworks/libmozjs.dylib/
/Contents/Resources/MaxPlugInScanner/
(only needed if your app uses the vst~ object)
上の引用文の中の、Contents/Framework/の下にある"libmozjis.dylib"は、javascript関連のFrameworkになりますが、現在は名前が変わっていて、2つあります。"libmozjs185_impl.dylib"、"libmozjs185.dylib"を削除します。
"MaxPlugInScanner"こちらも、"vst~"のオブジェクトを使っていなければ不要に書いてありますが、私の使ったアプリでは、このファイルが無くても"vst~"は動作しています。
さらに不要なファイルを追記しておくと、"Rewire"関連のファイルは、Rewireを使っていなければ必要ありません。"ad_rewire.mxo"、"MSPReWireDevice.bundle"、"midi_adrewire.mxo"がそれに当たります。
さらに、info.plistの書き換え
Maxでビルドされたアプリケーションは、複数のFrameworkと、~.mxoという実行ファイル群によって構成されています。
ですので、Contents/Framework/~.frameworkというファイルと、さらに、Contents/Resource/C74/extensionsと/externalsの下にある、全ての~.mxoというファイル。これらのさらに中にある"info.plist"ファイルを書き換える必要があります。~.mxoも、~.frameworkも再度「パッケージの内容を見る」をすると見つける事が出来ます。
数が多いので、「えっ」と思われるかもしれませんが、最初に書き換えたContents/直下の"info.plist"とは違って、書き換えるのは"Bundle identifier"の部分のみになります。
全てのinfo.plistの"Bundle identifier"を、最初に書き換えたinfo.plistと同様のこのアプリ独自のものに書き換えます。
仮にこの作業をミスしても、次の作業に移るとエラーが発生するので、ミスの原因は特定し易いです。作業は面倒ですが。
Sandboxingと、Code Signing
この二つの作業は、オフィシャルのドキュメントの【Part.4】【Part.5】そのままですので、割愛します。
注意点は、"Codesign"は、前述の全ての~.mxoと~.frameworkに行う必要があります。ここで、info.plistを書き間違えていると、エラーが出ますので注意してください。
"Codesign"が終わってしまうと、アプリ内のファイルの書き換えは出来ません。書き換えた場合は再度"codesign"を行えばオッケーです。
また、ビルドをやり直すと、当然全て書き換わってしまいますが、一度書き換えた~.mxo等と入れ替えても問題はありません。なので、info.plistの書き換えは一度で問題ありません。
また、問題無いのに、何度か、sandboxingと、code signingの作業でエラーが発生することがありました。ドキュメントにもありますが、以下のコマンドで解決することが出来ました。
xattr -lr ~/Desktop/APPLICATION.app
xattr -cr ~/Desktop/APPLICATION.app
.pkgファイルと"Transporter"
こちらも、オフィシャルのドキュメントのままで問題はありませんが、若干情報が違います。アップロードには、"Transporter"というアプリが必要になります。これは、MacAppStoreから入手可能です。
実際にアプリをStoreにアップする前には、Apple Developer Siteの方の準備が必要になります。
サポートのWebサイトの準備や、Storeに載せるドキュメントやアプリの画面写真なども必要です。
Transporterでアプリをアップして、審査が通るまで3段階の審査がありました。
まず、Trasporterのアップ中に、主にCodesignのエラーなどがチェックされます。これはアップ中にチェックされて、はじかれます。
無事にアップされても、やはりinfo.plist等の記述に問題が見つかれば、あれば2-3時間の間にエラーが返ってきます。
機械のチェックが終わって、ステイタスが審査中になって、初めてアプリ内の動作などの問題について審査されます。
Maxでビルドして、MacAppStoreするまでの過程をまとめて見ました。
アプリをアップする際のApple Developer Siteなどの手続きは、実際には煩雑な作業がありますが、その辺りは他にも解説されているサイトがありますので、割愛しました。
実際アプリをMacAppStoreにアップしてみて、多くの方に利用して貰うことで、レビューなどレスポンスもいただけるので、制作のモチベーションにも繋がります。実際に利益に繋げるのは中々ハードルも高いかと思います。
もし、MaxユーザーでMacAppStoreへのアップをチャレンジされている方がいたら、是非知見を共有したいと思っていますので、一言ご連絡いただけるとうれしいです。