スタディサプリ Product Team Blog

株式会社リクルートが開発するスタディサプリのプロダクトチームのブログです

Bundle version だけ変えた iOS アプリをシュッと作る

こんにちは、@manicmaniac です。 普段はスタディサプリの iOS 開発チームのマネージャーをしています。 前回 の投稿から1年ちょっとぶりの投稿です。

非常に限定された場面ではありますが、試行錯誤の時間を大幅に減らすことができる TIPS を紹介します。

困ったケース

あるタスクで、fastlane pilot を用いて TestFlight にビルドをアップロードする際の設定を最適化するために、何度かビルドをアップロードして挙動を観察する必要がありました。

ご存知の方も多いと思いますが、 TestFilght にビルドをアップロードする場合は Info.plist 中の CFBundleVersion を一意にする必要があります。 また、スタディサプリの iOS アプリではリリースビルドを作るのにおおむね 20分くらいの時間がかかります。

当初は実際にビルドを作成してアップロードを試していましたが、アップロードのたびに CFBundleVersion を編集して再ビルドするのは時間と手間がかかるため、再署名を試してみることにしました。

再署名

iOS アプリの再署名とは、既存の iOS アプリを別の証明書やプロビジョニングプロファイルを使って再度署名し、別の環境やデバイスで動作するようにすることを指します。

すでに fastlane を使っていたので、fastlane resign を使って署名を差し替えることができそうです。 よって、手元にすでにビルド済みの .ipa ファイルを入力として、CFBundleVersion を変更して .ipa に再署名するような lane を作ってみることにしました。

細部は変更していますが、おおむね以下のような lane になりました。

lane :bump_ipa_version do
  Zip::File.open(File.expand_path("../build/Release/MyApp.ipa", __dir__)) do |zip_file|
    # ipa を unzip して Info.plist を取り出す
    entry = zip_file.find_entry("Payload/MyApp.app/Info.plist")
    raise "Info.plist not found in ipa." unless entry

    plist = CFPropertyList::List.new(data: entry.get_input_stream.read)
    hash = CFPropertyList.native_types(plist.value)

    # 日時から一意な CFBundleVersion を作って保存する
    hash["CFBundleVersion"] = Time.now.strftime("%Y%m%d%H%M%S")
    plist.value = CFPropertyList.guess(hash)

    # ipa ファイルを上書きする
    zip_file.get_output_stream(entry.name) do |out|
      out.write(plist.to_str)
    end
  end
  # 再署名する
  resign(
    ipa: "build/Release/MyApp.ipa",
    signing_identity: "Apple Distribution: My Organization (XXXXXXXXXX)",
    provisioning_profile: {
      "com.my-company.MyApp" => "#{ENV.fetch("HOME")}/Library/MobileDevice/Provisioning Profiles/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.mobileprovision",
    },
  )
end

rubyzipCFPropertyList に依存してますが、これらは今 (2.225.0) のところ fastlane の依存でもあるので、新たな依存関係を追加せずに利用できます。

この lane を使うと数秒から十数秒くらいのわずかな時間で CFBundleVersion を変更した ipa ファイルができるようになりました。

スクリプトを書くのに多少の時間を使いましたが、このあと何度もアップロードを繰り返したことを考えると、充分に手間と時間を節約できたと思います。

所感

様々な目的で iOS アプリの再署名をする事例は世の中にたくさんありますが、これまであまり使ったことはありませんでした。 今回使ってみることで意外と簡単に再署名ができること、ipa の書き換えと組み合わせると他にも有用そうなユースケースがありそうということをあらためて発見しました。

この記事がいつかどこかで、同じような課題を抱えるどなたかの助けになれば幸いです。