Joseph O'Shea

Correcting my mental model of Cocoapods - the contents of Pods/ does matter!

cocoapodsreact-nativexcodeios

Background / 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:

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 of Podfile, Podfile.lock, and node_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 of Podfile, Podfile.lock, and node_modules

What I was observing here seemed to suggest it wasn't. To recap, I had just seen very clearly:

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:

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 of Podfile, Podfile.lock, node_modules, and Pods/