Podfile.lock と SPEC CHECKSUMS

2020/09/26に公開

想定読書

  • CocoaPods を使ったことがある。
  • pod install pod update など CocoaPods の基本的な仕組みについて知っている。

はじめに

Swifit や Objecttive-C で開発する際に CocoaPods でライブラリの依存管理を行うのはデファクトスタンダードになっています。

先日 Xcode でアプリをビルドしたときに遭遇したエラーについて調査した際に得た CocoaPods 、特に Podfile.lock に関する知見をまとめます。

The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

なにこのエラー

sandbox が Podfile.lock と同期していないから pod install してくれや、というエラーです。
sandboxってなんでしょう。何がエラーの直接の原因なんでしょう。なぜ pod install で直るのでしょう。
今回はそれに関して調べてみました。

sandboxとは

調べてみたところ CocoaPods のなにかというより、外界から隔離された環境、すなわちローカル環境のことを言っているみたいです。

sandnox のキーワードで CocoaPods の公式サイト内を検索してみました がなんの手がかりも得られませんでした。

エラーの原因を探る

では git 管理された Podfile.lock がローカル環境のなにと食い違っているのでしょうか。
このままでは手がかりがなにもないので pod install してみます。

% pod install

Podfile.lock が更新されたみたいです。

% git diff 
diff --git a/Podfile.lock b/Podfile.lock
index 9b0777362..d4f3730a1 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -303,11 +303,11 @@ SPEC CHECKSUMS:
   Alamofire: 85e8a02c69d6020a0d734f6054870d7ecb75cf18
   AMScrollingNavbar: cf0ec5a5ee659d76ba2509f630bf14fba7e16dc3
   AppAuth: 73574f3013a1e65b9601a3ddc8b3158cce68c09d
-  Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df
+  Crashlytics: 9220f5bc89e7a618df411b4f639389dbfb0e03d2
   CryptoSwift: 769f58a9e89f64e8796c2e59ce5f002dc81a2438
   DifferenceKit: 516f12e336ed65a3a0665847b5c3cb5cad4bd4ea
   ExpandableLabel: c2fab6d27860c572d67134b30522a5917746171d
-  Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74
+  Fabric: ea977e3cd9c20425516d3dafd3bf8c941c51223f
   FBSDKCoreKit: 1d5acf7c9d7a2f92bb1a242dc60cae5b7adb91df
   FBSDKLoginKit: f1ea8026a58b52d30c9f2e6a58ca7d813619fb83
   Firebase: 497158b816d0a86fc31babbd05546fcd7e6083ff
@@ -357,4 +357,4 @@ SPEC CHECKSUMS:
 
 PODFILE CHECKSUM: 24964df446a6a8cfbf76c10fc9bcb9bb71359400
 
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.3

無事? Pod のインストールが完了し、 Podfile.lock が更新されました。
podfile.lock は git 管理されているライブラリとそのバージョンの情報なので、直感的には pod install しただけでは更新されない気がしますが何が変わったんですかね。

この手がかりから Podfile.lock について理解を深めていきます。

Podfile.lock

上記 git 差分のあった箇所を見ていきます。

COCOAPODS

ここはおそらく CocoaPods のバージョンを管理しているのでしょう。
どのバージョンの CocoaPods を使って pod installpod update のコマンドを叩いたかということです。

おそらく、というのは公式ガイド内で言及している記事を見つけることができませんでした。
念の為の確認です。

% pod --version
1.9.3

どうやらレポジトリを共有しているメンバーの間で使っている CocoaPods のバージョンに差分があるらいしということがわかりました。

SPEC CHECKSUMS

もう1箇所差分がありました。
ライブラリ Crashlytics に関する何かしらのハッシュ値らしき値が更新されています。

-  Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df
+  Crashlytics: 9220f5bc89e7a618df411b4f639389dbfb0e03d2

SPEC

Spec について公式ガイドでは下記のような記載がありました。

A Podspec, or Spec, describes a version of a Pod library. One Pod, over the course of time, will have many Specs. It includes details about where the source should be fetched from, what files to use, the build settings to apply, and other general metadata such as its name, version, and description.

Spec は Pod (ライブラリ)を管理するメタ情報を扱っているファイルとのこと。

  • ソースコードをどこから取ってくるか
  • どのファイルを使うのか
  • 適用するビルドの設定
  • その他一般的なメタデータ
    • 名前
    • バージョン
    • 説明

通常自分で Pod のライブラリを作製、管理する際に使うみたいです。

SPEC REPO

そんな SPEC ですが、GitHub の Specs Repo のレポジトリで管理されています。

実はこのレポジトリはローカルにも下記のパスでクローンされています。

~/.cocoapods/repos/master/

Clashlytics の Specs もレポジトリ内に見つけることができました。

% find . -name Crashlytics -type d 
./Specs/3/6/0/Crashlytics

見てみると、 JSON 形式で Crashlytics に関するメタデータが管理されています。

{
  "authors": "Google",
  "dependencies": {
    "Fabric": [
      "~> 1.10.2"
    ]
  },
  "frameworks": [
    "Security",
    "SystemConfiguration"
  ],
  "homepage": "http://try.crashlytics.com/",
  "libraries": [
    "z",
    "c++"
  ],
  "license": {
    "text": "Fabric: Copyright 2018 Google, Inc. All Rights Reserved. Use of this software is subject to the terms and conditions of the Fabric Software and Services Agreement located at https://fabric.io/terms. Crashlytics Kit: Copyright 2018 Crashlytics, Inc. All Rights Reserved. Use of this software is subject to the terms and conditions of the Crashlytics Terms of Service located at http://try.crashlytics.com/terms/terms-of-service.pdf and the Crashlytics Privacy Policy located at http://try.crashlytics.com/terms/privacy-policy.pdf. OSS: http://get.fabric.io/terms/opensource.txt",
    "type": "Commercial"
  },
  "name": "Crashlytics",
  "platforms": {
    "ios": "7.0",
    "osx": "10.7",
    "tvos": "9.0"
  },
  "preserve_paths": [
    "submit",
    "Crashlytics.framework/*"
  ],
  "source": {
    "http": "https://kit-downloads.fabric.io/cocoapods/crashlytics/3.14.0/crashlytics.zip"
  },
  "summary": "Best and lightest-weight crash reporting for mobile, desktop and tvOS.",
  "version": "3.14.0",
  "ios": {
    "source_files": "iOS/Crashlytics.framework/Headers/*.h",
    "public_header_files": "iOS/Crashlytics.framework/Headers/*.h",
    "vendored_frameworks": "iOS/Crashlytics.framework"
  },
  "osx": {
    "source_files": "OSX/Crashlytics.framework/Versions/A/Headers/*.h",
    "public_header_files": "OSX/Crashlytics.framework/Versions/A/Headers/*.h",
    "vendored_frameworks": "OSX/Crashlytics.framework"
  },
  "tvos": {
    "source_files": "tvOS/Crashlytics.framework/Headers/*.h",
    "public_header_files": "tvOS/Crashlytics.framework/Headers/*.h",
    "vendored_frameworks": "tvOS/Crashlytics.framework"
  },
  "deprecated_in_favor_of": "FirebaseCrashlytics"
}

SPEC CHECKSUMS は結局なんなのか

結論を先に言うと SPEC REPOS はまさにこの Spec の JSON のハッシュ値になります。

% cat ~/.cocoapods/repos/master/Specs/3/6/0/Crashlytics/3.14.0/Crashlytics.podspec.json | openssl sha1
9220f5bc89e7a618df411b4f639389dbfb0e03d2

SPEC CHECKSUMS はなんのためにあるのか

この仕組のお陰で podfile.lock の SPEC CHECKSUMS と、ローカルの Spec の JSON との間の差分が検知でき、 Pod が異なることによるインシデントを回避することができます。

なぜ pod install でエラーが fix されたか

pod install で Podfile.lock が更新されたことでpodfile.lock の SPEC CHECKSUMS と、ローカルの Spec の JSON との間の差分がなくなり、エラーを回避することができます。

ちなみによくよく調べてみると Crashlytics の Spec の更新が4日前に行われており ローカルの Spec ファイルに対して git 管理されている Podfile.lock が古いためにこのような差分が発生していたことがわかりました。

今回は Spec ファイルの更新がライブラリのメタ情報として些細なものだったためこれ以上の対応は不要と判断しましたが、もしソースの入手先が変わっているなどした場合には軽めにでもアプリの動作チェックをする必要があると思います。

エラーの fix は単純ですが、発生した背景を知らずにいるといつか事故る未来が来るかも知れませんね。どきどき。

最後に

最後までご覧いただきましてありがとうございます。
記事は出来る限り一次ソースを追って記載するようにしていますが、確認できない内容もありました。
誤っている箇所や詳細な情報をお持ちでしたらぜひ共有お願いいたします。

参考

Discussion