Correcting my mental model of Cocoapods - the contents of Pods/ does matter!
cocoapodsreact-nativexcodeiosBackground / Motivation #
Lately I've been focusing more on explicitly understanding, testing and validating/invalidating my mental models of how things work. Sometimes in the normal course of work, I notice something (often small) which runs contrary to my current mental model of how something wrks. I am trying to practice the habit of taking these moments to stop, investigate, learn where my mental model was wrong, and update it accordingly.
My previous mental model of cocoapods #
I recently had this experience with cocoapods. I use pod install
quite frequently working on React Native projects. My mental model of how cocoapods worked was quite similar to how my mental model of npm
and yarn
work:
- you have a file that defines your dependencies and rules about version ranges (e.g.,
package.json
/Podfile
) - you have a lockfile, which pins the specific versions of your dependencies for reproducable results (e.g.,
package-lock.json
/Podfile.lock
) - when you install (e.g.,
npm install
orpod install
) the result of that command is derived from the two above files
For cocoapods, there is one addition to that. I know that in React Native, many Pods come from node_modules
, like so:
pod 'React', :path => "../node_modules/react-native"
So summing that up - my previous mental model (before this experience) of how pod install
worked was:
The result of
pod install
in a React Native project is dependent only on the state ofPodfile
,Podfile.lock
, andnode_modules
However, I saw something that ran contrary to that and had to update my model.
The error that got my attention #
I was getting this error when trying to pod install
:
[ 11:35AM ] [ joey@devmachine:~/dev/my-react-native-app/ios(main✔)ruby-3.1.1 ]
$ pod install
...[truncated]...
[!] CocoaPods could not find compatible versions for pod "RCT-Folly":
In snapshot (Podfile.lock):
RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
In Podfile:
RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
It seems like you've changed the version of the dependency `RCT-Folly` and it differs from the version stored in `Pods/Local Podspecs`.
You should run `pod update RCT-Folly --no-repo-update` to apply changes made locally.
I was surprised, because this branch seemed to work before.
I did however recall I had just been on another branch (let's call it chore/upgrade-sdk
) which made significant changes to our Podfile (as the name implies, this branch was an upgrade to major native SDKs in the app).
But this branch (main
) was clean!
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
I did the command pod update RCT-Folly --no-repo-update
and it did fix things. But then, I did git reset --hard
and ran pod install
again and it worked!
This violated a key part of my mental model about cocoapods. To repeat, my assumption was:
The result of
pod install
in a React Native project is dependent only on the state ofPodfile
,Podfile.lock
, andnode_modules
What I was observing here seemed to suggest it wasn't. To recap, I had just seen very clearly:
- on a clean
main
branch (nothing to commit, working tree clean) in a known good state,pod install
failed - running
pod update RCT-Folly --no-repo-update
on that branch did fix the problem - resetting back to a clean branch with
git reset --hard
causedpod install
to work again.
My hypothesis was that the Pods/
directory was causing the problem. This directory is ignored by .gitignore
, so it wouldn't be reset by checking out a new branch or using git reset --hard
.
So I set out to test this hypothesis to see if I needed to update my mental model.
Testing the hypothesis #
So I had two branches:
main
--> known good state, builds known to workchore/upgrade-sdks
--> new WIP branch with major SDK upgrades, therefore big changes toPodfile.lock
andPods/
The test:
git checkout main
rm -rf node_modules
yarn
cd ios
pod install
This works ✅
Now
git checkout chore/upgrade-facebook-and-segment-sdks
rm -rf node_modules
yarn
cd ios
pod install
This breaks ❗ (same error as before)
Now, what if we:
rm -rf Pods/
pod install
This works! ✅
Meaning the git checkout
step is not enough. We also need to delete Pods/
💡
Updating my mental model #
After this learning experience, I have now update my mental model:
The result of
pod install
in a React Native project is dependent only on the state ofPodfile
,Podfile.lock
,node_modules
, andPods/