少し前にelectronMastodonクライアントを作ったのだが,ようやくそれをMacAppStoreに登録した.
ちゃんと公開されてる.
そいえば前にelectronのリリース用パッケージについても書いた. 今日はその続きということで,MacAppStoreへの公開までを書く.
証明書を用意する
今回は,通常のMac用ビルドは通ることを前提にしている.なお,もちろんAppleDeveloperProgramへの登録も済んでいることを前提にする.
AppStoreで配布するのだから当然証明書が必要になる.リリースするためには以下の証明書が必要になる.
前回同様,CertificateSigninRequestを作成しよう.
そしたら,developer.apple.comのCertificates, Identifiers & Profilesに行く. で,macOSのCertificatesとして,Mac App DistributionとMac Installer Distributionを作成し,これをダウンロードしておこう.
ダウンロードした2つの証明書をダブルクリックし,キーチェーンに登録しよう.
キーチェーンを見た時に,
が入っていれば問題ない.
ビルドしてpkgファイルを作る
今回はelectron-packagerを使う.前回,electron-builderを使えばelectron-packagerは今や不要と書いたが,masに関してはelectron-builderで証明書周りをクリアできなかった. もしかしたらもっと上手いやり方があったのかもしれないが,とりあえずドキュメントを読んだだけでは鍵の設定方法が謎い. なによりCodeSignされない気がする.
というわけでelectorn-packagerを使う.
$ npm run pack && electron-packager ./ 'Whalebird for Mastodon' --platform=mas --arch=x64 --electron-version=1.8.3 --asar.unpackDir='build/sounds' --out=packages --ignore='^/src' --ignore='^/test' --ignore='^/.electron-vue' --ignore='^/.envrc' --ignore='^/packages' --ignore='^/plist' --ignore='^/static' --prune=true --icon=./build/icons/icon.icns --overwrite --app-bundle-id=org.whalebird.desktop --app-version=$npm_package_config_appVersion --build-version=$npm_package_config_buildVersion --extend-info='./plist/team.plist' --osx-sign --app-category-type=public.app-category.social-networking
こんなコマンドになる. 俺は,覚えるのは不可能なので,package.jsonに書いた.
大事なこと: plist
--extend-info
でplistを指定している.ここではアプリに作成者の情報を渡すためにplistを用意している.
plistとしては,
- team.plist
- parent.plist
- child.plist
- loginhelper.plist
という4つのファイルを作っている. electorn-pcakgerではteam.plistしか使用していない.他のplistについてはCodeSignの段階で使用するので,とりあえずteam.plistについてだけ説明する.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ElectronTeamID</key> <string>team_id</string> </dict> </plist>
こんなファイルになっている. team_idについては,証明書にも記述されているし,iTunesConnect等でも確認できる.
大事なこと: asar.unpackDir
Whalebirdは音声ファイルを使用しており,音声ファイルだけはasarに圧縮されるとアクセスできなくなってしまう. そのため,electron-builderでもextraResourcesを使ってasar圧縮から除外していた.
electron-packagerではasar.unpackDir
というコマンドでこれを実現している.
出来上がったパッケージ内の, Contents/Resources/app.asar.unpacked/
にファイルが置かれるので,ビルド後にこのパスをelectron-builderで作ったものに合わせる必要がある.
これで今までとプロダクトコードを変更せずに,配布したアプリケーションで音声を再生できるようになる.
CodeSignする
electron-packagerでパッケージを作成しただけでは,AppStoreに配布することはできない. これにcodesignという処理をかけてやる必要がある.
plist
まず,先ほど説明を飛ばしたplistファイルを3つ作る.
- parent.plist
- child.plist
- loginhelper.plist
parent.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.application-groups</key> <string>team_id.org.whalebird.desktop</string> <key>com.apple.security.files.user-selected.read-only</key> <true/> <key>com.apple.security.network.client</key> <true/> </dict> </plist>
ここで,アプリに許可する動作を列挙する.
Whalebirdでは画像投稿を許可しているため,files.user-selected.read-only
.
そしてmastodonサーバと通信するための network.client
を許可している.
項目については,
こちらで確認できる.
child.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.inherit</key> <true/> </dict> </plist>
childはparentを継承するので特に権限の設定をここで追加する必要はない.inherit
してあれば十分.
loginhelper.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> </dict> </plist>
これにつても特別な権限を設定する必要はない.
CodeSign
plistが用意できたら,CodeSignしよう.
# Name of your app. APP="Whalebird for Mastodon" # The path of your app to sign. APP_PATH="./packages/Whalebird for Mastodon-mas-x64/Whalebird for Mastodon.app" # The path to the location you want to put the signed package. RESULT_PATH="./packages/$APP.pkg" # The name of certificates you requested. APP_KEY="3rd Party Mac Developer Application: name (team_id)" INSTALLER_KEY="3rd Party Mac Developer Installer: name (team_id)" # The path of your plist files. CHILD_PLIST="./plist/child.plist" PARENT_PLIST="./plist/parent.plist" LOGINHELPER_PLIST="./plist/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" # At first, rename app.asar.unpacked directory. # Because electron-builder does not store app.asar.unpacked directory. # I want to store unpacked files at the same directory as electron-builder. mv $APP_PATH/Contents/Resources/app.asar.unpacked/* $APP_PATH/Contents/Resources/ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"
こんなコマンドを叩く必要がある.ここで,最初に作った証明書の名前を埋めておこう.
これを実行すると.pkg
ファイルが作成される.
あとはこれをアップロードすれば良い.
動作確認
一応動作確認しておく.ここで動かなければAppStoreに登録しても動くはずがない.
まず,$APP_PATHにあるアプリケーションを消しておこう.これがあると,既にインストール済みと判定されて.pkg
ファイルが何もしてくれなくなる.
そうしたら.pkg
ファイルをダブルクリックし,インストーラーを実行する.
すると /Applications
以下にアプリケーションがインストールされるので,実行してみよう.
iTunesConnectでアプリとバージョンを作成
アプリケーションがビルドできたとして,次はアップロード先を作っておかないといけない.このへんはswift等でiOSアプリを作ったことがあると慣れっこである.
iTunesConnectに行き,新しいアプリケーションを作る.
最初はバージョンが1.0
になっている.セマンティックバージョニングを使いたければ,バージョン情報から番号を編集できる.
ApplicationLoaderでアップロード
Xcodeを開く.
Xcode -> Open Developer Tool -> Application Loader でApplicationLoaderを開く.そうしたら先ほどiTunesConnectで作成したアプリ向けに.pkg
ファイルをアップロードすれば良い.
審査を通す
iTunesConnectでバージョン情報や連絡先等,必要な情報を全部埋めたら,審査にだそう. どうやったら審査に通るかは謎いが,変なアプリじゃなければだいたい通るんじゃないかな.
幸いなことにWhalebirdは一発で審査が通った.最近のAppleは審査が早くなったのでやりやすい.