この記事はくふうカンパニー Advent Calendar 2018の6日目の記事です。
手作業を減らせばミスが減り、開発に集中する時間が生まれるため、なるべく自動化したいところです。
そんな思いで行なっている、iOSアプリ開発における自動化のTipsを共有したいと思います。
fastlane
モバイルアプリ開発を便利にしてくれるRuby製のツールです。
自分はプロジェクト直下にGemfileを置いてbundle install --path vendor/bundler
を叩いて(bundlerが入っていない方はgem install bundler
を事前に行なっておく)gemを入れて導入しています。楽です。
ここからは自分が普段行なっている作業を書いていきます。
リリース作業
リリース作業というと
- バージョンを変える
- ビルド番号を変える
- アーカイブする
- AppStoreConnectにアップロード
- git関連(commitしたりtag打ったり)
あたりが必須の作業になると思いますが、手作業だと面倒だしミスする可能性もあります。
fastlaneを使うと
increment_build_number
upload_to_app_store
などactionが用意されており、それをFastfileに書いていくとリリース用のlaneが出来上がります。
以下参考のlane.
bundle exec fastlane release ver:{#ver(例: 1.0.0)}
とコマンドを叩くと順に実行されていきます。
before_all do
ENV["SLACK_URL"] = "your slack url"
end
desc "App Store Connectにアップロード"
lane :release do |options|
number = increment_build_number
# verを指定しなければpatchが上がる
ver = increment_version_number(
version_number: options[:ver]
)
cocoapods
carthage(
use_binaries: false,
platform: "iOS",
configuration: "Release",
cache_builds: true
)
build_ios_app(
scheme: "Release"
)
# ENV["APPLE_ID"]をアップロードを行う人は自分の端末に設定しておくこと
# screenshotsはUITestで使っているためスキップ
upload_to_app_store(
force: true,
skip_metadata: true,
skip_screenshots: true
)
slack(
message: "アップロード完了"
)
message = "ver#{ver}(#{number})をアップロード"
git_add
git_commit(
path: "./*",
message: message
)
add_git_tag(
tag: "#{ver}"
)
push_to_git_remote
# GITHUB_API_TOKENを環境変数として登録しておくとターミナルで聞かれなくて楽
create_pull_request(
repo: "your repository",
title: message
)
sh("say", "-v", "Kyoko", "おめでとうございます。リリース作業が完了しました。")
end
GithubにPull Requestを送る
git関連の作業は全部fastlaneでやってしまえば良いのでは? という思いつきから作ったのですが意外と便利です。
こういう使い方をfastlaneでやっている人はあまり見かけませんがカスタマイズして使ってみてください。
desc "developブランチへのpull requestを作る"
lane :pr do |options|
message = options[:message]
git_add
git_commit(
path: "./*",
message: message
)
push_to_git_remote
title = options[:title] || git_branch
create_pull_request(
repo: "your repository",
base: "develop",
title: title
)
end
dsymのダウンロード・アップロード
Appleが推奨しているのでbitcodeを有効にしているのですが、後述するクラッシュ計測ツールの分析がそのままだと行えません。dsymをダウンロードしてアップロードして、というのも面倒なのでlaneを用意しました。
desc "Crashlyticsにdsymをアップロードする"
lane :dsyms do
download_dsyms # Download dSYM files from iTC
upload_symbols_to_crashlytics # Upload them to Crashlytics
clean_build_artifacts # Delete the local dSYM files
end
参考: https://krausefx.com/blog/download-dsym-symbolication-files-from-itunes-connect-for-bitcode-ios-apps
自動スクリーンショット生成
端末ごとにどんな画面になっているのか見たい場面というのはあります。
だいたい下記の記事を参考にしてもらえると良いです。
bundle exec fastlane snapshot
を叩いてある程度時間が経つとSnapfileで設定した端末のスクショが吐き出されていて気持ち良いです。
参考: https://docs.fastlane.tools/getting-started/ios/screenshots/#setting-up-snapshot
LicensePlist
アプリの中で利用しているOSSライブラリを、iOS標準の設定アプリに載せるというのが慣習となっています。
ただ、これを自作するのは結構手間がかかります。
そんな問題を解決しているのがLicensePlistです。
約1300Starを獲得している素晴らしいツールです。(Star数は2018/12/6時点)
導入はとても楽です。
自分はHomebrewで入れているのですがCocoaPodsでも入れられるそうです。
Homebrewでinstallした後にxcodeprojファイルのBuild Phases
からRun Script Phase
を選択してスクリプトを追加するとアプリビルド時に更新のあったライブラリを検知してライブラリ一覧を生成・更新してくれます。
詳しくは作者様のGithubのREADMEをどうぞ。
https://github.com/mono0926/LicensePlist
GAS + SlackでAppStoreConnectのステータスを通知
参考にしたのはこちらのスライドです。
AppStoreConnectのメールが来ないけど審査状況が気になる人、メールは届くのだけれどメールよりもSlackに通知される方が便利だと感じる人がそれなりにいたのでGoogleAppsScriptで書きました。
以下参考。
function onGotMail(subject, appname) {
try {
var threads = GmailApp.search(subject);
var messages = GmailApp.getMessagesForThreads(threads);
for (var i in messages) {
for (var j in messages[i]) {
var message = messages[i][j];
message.markRead();
var subject = message.getSubject();
var body = message.getBody();
// Version Numberはリジェクトメールに含まれないのでここでmatch判定
if (subject.match(/New Message from App Store/)) {
postSlack("Appleからのメールを確認しましょう。", appname);
}
var matched = body.match(/Version Number:\s+(\d+.\d+.\d+|\d+.\d+)/);
if (matched) {
var username = "ver" + matched[1] + appname;
if (subject.match(/has completed processing/)) {
postSlack("申請作業ができるようになりました! TestFlightで確認してから申請作業を行いましょう!", username);
} else if (subject.match(/Waiting For Review/)) {
postSlack("審査に出しました。1,2日ほどお待ちください。", username);
} else if (subject.match(/In Review/)) {
postSlack("審査中です……", username);
} else if (subject.match(/Pending Developer Release/)) {
postSlack("審査が通りました! AppStoreで公開しましょう!", username);
} else if (subject.match(/Ready for Sale/)) {
postSlack("公開作業が完了しました! AppStore反映まで1, 2時間ほどお待ちください。", username);
}
}
}
}
} catch(error) {
postSlack("GASでエラーが発生しました。エラーログ用のスプレッドシートを確認してください。", appname);
logging(JSON.stringify(error));
}
}
その他外部ツール
AppFollow
アプリのレビューやAppStoreでの検索キーワードの順位を教えてくれるツール。
Slackに流しています。無料プランで結構十分です。
AmazonPinpoint, Firebase
モバイル分析ツール。どの画面を見てどのような動きをしたか計測できます。
Firebaseの方がダッシュボードが見やすく使っている人が多いので情報も豊富ですが、Amazon Pinpointの方はセッションヒートマップが見れたり定期的なプッシュ通知が送れたりします。
どちらも一長一短あるなという印象です。
Crashlytics
クラッシュ解析ツール。ユーザーがアプリでクラッシュしたらこちらに飛んでくるので、バグをより早く減らせるようになりました。
どの画面でなんのイベントを行ったか、端末のOSやアプリバージョンなどがわかるのでそれを元に調査することとなります。
まとめ
いかがでしたでしょうか?
余力があればCIやSwiftlintなども導入してみると良いと思います。
ガンガン自動化して開発に集中しましょう!