How do you reduce the time needed for `pod install` with Cocoapods for a project with many dependencies? - cocoapods

My project has about 60 dependencies, listed one after another...
platform :ios, '7.1'
inhibit_all_warnings! # This will disable all the warnings for all pods!
target 'MyProj' do
pod 'First'
pod 'Second'
... # 57 more pods
pod 'Last'
end
Every pod install takes about 3-4 minutes.
When trying to restructure the project in to smaller pods, it takes hours and hours to change extract the relevant dependencies into private pods and it is very expensive to iterate.
How can I work on Podfiles and splitting application modules up more effectively?

Depending on the bottleneck that is happening you can try running pod install and telling CocoaPods not to update the specs repo:
pod install --no-repo-update
Note that this will cause issue if you add a new version of a pod that has not been downloaded locally let in which case you'll want to run:
pod repo update

Related

Library not loaded: #rpath/hermes.framework/hermes

I have enabled Hermes in my react-native(v0.64) Application. Everytime I run app I get following stack trace.
dyld: dyld cache load error: shared cache file open() failed
dyld: Library not loaded: #rpath/hermes.framework/hermes
Referenced from: /Users/sharktank/Library/Developer/CoreSimulator/Devices/A32F4931-51A8-4D22-AEFB-625F834CE221/data/Containers/Bundle/Application/71773888-08D5-4B82-9545-07F6B1538864/COSPM-DEV.app/COSPM-DEV
Reason: image not found
dyld: launch, loading dependent libraries
DYLD_SHARED_CACHE_DIR=/Users/sharktank/Library/Developer/CoreSimulator/Caches/dyld/20E232/com.apple.CoreSimulator.SimRuntime.iOS-14-4.18D46
DYLD_ROOT_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot
DYLD_LIBRARY_PATH=/Users/sharktank/Library/Developer/Xcode/DerivedData/COSPM-atbujvbobdbyehckyoqrdgmqiubm/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSim
(lldb)
I have enabled hermes in Podfile and after pod install pod is available in Pods folder.
Project is in monorepo architecture along side another projects. Another app enabled with Hermes in same mono-repo package is working fine without crash.
Podfile:
require_relative '../../../node_modules/react-native/scripts/react_native_pods'
require_relative '../../../node_modules/#react-native-community/cli-platform-ios/native_modules'
platform :ios, '10.0'
source 'https://github.com/CocoaPods/Specs.git'
target 'COSPM' do
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => true
)
pod 'RNVectorIcons', :path => '../../../node_modules/react-native-vector-icons'
# Firebase
pod 'Firebase'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'CodePush', :path => '../../../node_modules/react-native-code-push'
target 'COSPMTests' do
inherit! :complete
# Pods for testing
end
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
use_flipper!()
post_install do |installer|
react_native_post_install(installer)
end
end
I am using Xcode 12.4.
Solutions I tried which did not work:
Clean Pods and npm packages, clean previous build and rebuild
Clear watchman and metro bundler cache and rebuild
I was facing the same problem on react native 0.70
Select App Target then follow the steps
goto Build Phases
Inside Link Binary With Libraries section
Click on Add Items and search for hermes.xcframework and add it
Rebuild application
This resolved my issue in RN 0.70. In Xcode, Targets -> Build Phases -> Link Binary With Libraries
The other answers suggest disabling Hermes or manually adding it as a linked library, but this should not be necessary.
The latest version should install the Hermes framework automatically.
The problem seems to be related to using the incorrect version of CocoaPods and the pods repo.
To bring everything up to date, do the following:
Make sure your Gemfile is up to date for your version of React Native. You can use the Upgrade Helper to see if it needs changed.
Upgrade Ruby to the version listed in your project's Gemfile. (Instructions)
Upgrade CocoaPods to the latest version: bundle install
Update the CocoaPods repo: bundle exec pod repo update
Delete Podfile.lock
Reinstall pods cd ./ios && bundle exec pod install
If you're still getting errors, double check that the correct versions are actually being used (are in your PATH).
I also made a blog post about this error if you would like more details: https://traviswimer.com/blog/cocoapods-could-not-find-compatible-versions-for-pod-hermes-engine/
Update (Jan 17, 2023)
I updated this answer to use the Bundler tool to manage Ruby and Cocoapods versions. The bundle command is now the recommended way to use Cocoapods in React Native projects. It runs commands based on the versions listed in your project's Gemfile (which is updated with each version of React Native). If for some reason you are unable to use bundle, you can manually upgrade Cocoapods using: gem install cocoapods
Then run the other commands without bundle exec. (e.g. pod repo update and pod install
Try following:
Change hermes_enabled value from true to false in Podfile
Reinstall npm/yarn dependencies by (yarn install)
Reinstall pods (cd ios && pods install)
Run app (react-native run-ios)
I tried this a couple of times changing hermes_enabled from true to false and back, and once it starts working.
The right answer depends on your react-native version
This error means that your react-native project is set to use hermes a lightweight Javascript engine created by facebook specially for react-native. It is supposed to make the app faster and lighter.
If you want to use hermes, open your Podfile (ios/Podfile), look for hermes_enabled and set its value to true. The line should look like the following
:hermes_enabled => true
Besides that, you might needs to follow few more steps from the official page.
If your Podfile does not have any hermes_enabled property, please make sure your react-native project is using at least 0.60.
For react-native > 0.60 and < 0.70
follow these steps from the official page.
For react-native >= 0.70
Hermes is the default engine for this version and beyond. Maybe you just need to reinstall your node packages, clean your Podfile.lock and reinstall your pods by running pod install from inside your ios folder.

Remove a specific pod from Xcode project

I need to remove a specific CocoaPod from my Xcode project. Browsing similar questions here on Stack Overflow, I ran into situations where the leading answer caused me to remove all my pods from the project and delete the workspace. Another answer suggested I simply needed to delete the pod from my Podfile and then run pod install, but that doesn't work either; I got several errors related to that pod when I went to build the app.
If I check the Pods folder via Finder, the deleted pods are no longer there. However, if I check Pods > Targets via the workspace, I still see the pods I deleted. They are also still in the Pods > pods directory in the workspace.
For now, I've deleted the related pods from the Pods > Targets area and the app builds fine. The pods are still in my Pods > pods directory though. Can I delete those? And, should pod install be handling all this for me in one go?
You deleted specific pods your app. For examples your podfile
target 'AppTargetName' do
use_frameworks!
pod 'Alamofire'
pod 'SwiftyJSON'
pod 'OneSignal'
pod 'Fabric'
end
if You want to delete only Fabric pods, you remove this and terminal commant pod install
So in the last case;
target 'AppTargetName' do
use_frameworks!
pod 'Alamofire'
pod 'SwiftyJSON'
pod 'OneSignal'
end
Good works :)
You want to remove specific pods your app. For examples your podfile
Your podfile have
pod 'FirebaseAuth'
pod 'FirebaseFirestore'
pod 'FirebaseDatabase'
Remove one of your doesn't need (pod 'FirebaseDatabase')
pod 'FirebaseAuth'
pod 'FirebaseFirestore'
Then open the terminal of directory of your project podfile
pod install

How to update a single pod without touching other dependencies

I understand that the following command will update a single pod: pod update <podname>. However this also updates the dependencies of other pods (pods that were not included in the update command) that you have previously installed. Is there a way to update a single pod and leave all other dependencies alone?
Make sure you have the latest version of CocoaPods installed.
$ pod update PODNAME was introduced recently.
See this issue thread for more information:
$ pod update
When you run pod update SomePodName, CocoaPods will try to find an updated version of the pod SomePodName, without taking into account the version listed in Podfile.lock. It will update the pod to the latest version possible (as long as it matches the version restrictions in your Podfile).
If you run pod update without any pod name, CocoaPods will update every pod listed in your Podfile to the latest version possible.
To install a single pod without updating existing ones-> Add that pod to your Podfile and use:
pod install --no-repo-update
To remove/update a specific pod use:
pod update POD_NAME
Tested!
It's 2015
So because pod update SomePod touches everything in the latest versions of cocoapods, I found a workaround.
Follow the next steps:
Remove SomePod from the Podfile
Run pod install
pods will now remove SomePod from our project and from the Podfile.lock file.
Put back SomePod into the Podfile
Run pod install again
This time the latest version of our pod will be installed and saved in the Podfile.lock.
just saying:
pod install - for installing new pods,
pod update - for updating existing pods,
pod update podName - for updating only specific pod without touching other pods,
pod update podName versionNum - for updating / DOWNGRADING specific pod without touching other pods
You can never get 100% isolation. Because a pod may have some shared dependencies and if you attempt to update your single pod, then it would update the dependencies of other pods as well. If that is ok then:
tl;dr use:
pod update podName
Why? Read below.
pod update will NOT respect the podfile.lock. It will override it — pertaining to that single pod
pod install will respect the podfile.lock, but will try installing every pod mentioned in the podfile based on the versions its locked to (in the Podfile.lock).
This diagram helps better understand the differences:
The major problem comes from the ~> aka optimistic operator.
Using exact versions in the Podfile is not enough
Some might think that specifying exact versions of their pods in their Podfile, like pod 'A', '1.0.0', is enough to guarantee that every user will have the same version as other people on the team.
Then they might even use pod update, even when just adding a new pod, thinking it would never risk updating other pods because they are fixed to a specific version in the Podfile.
But in fact, that is not enough to guarantee that user1 and user2 in our above scenario will always get the exact same version of all their pods.
One typical example is if the pod A has a dependency on pod A2 — declared in A.podspec as dependency 'A2', '~> 3.0'. In such case, using pod 'A', '1.0.0' in your Podfile will indeed force user1 and user2 to both always use version 1.0.0 of the pod A, but:
user1 might end up with pod A2 in version 3.4 (because that was A2's latest version at that time)
while when user2 runs pod install when joining the project later, they might get pod A2 in version 3.5 (because the maintainer of A2 might have released a new version in the meantime).
That's why the only way to ensure every team member work with the same versions of all the pod on each's the computer is to use the Podfile.lock and properly use pod install vs. pod update.
The above excerpt was all derived from pod install vs. pod update
I also highly recommend watching what does a podfile.lock do
Just a small notice.
pod update POD_NAME
will work only if this pod was already installed. Otherwise you will have to update all of them with
pod update
command
I'm using cocoapods version 1.0.1 and using pod update name-of-pod works perfectly. No other pods are updated, just the specific one you enter.
This is a bit of an outlier and not likely to be what the OP was dealing with, but pod update <podname> will not work in all cases if you are using a local pod on your computer.
In this situation, the only thing that will trigger pod update to work is if there is a change in the podspec file. However, making a change will also allow for pod install to work as well.
In this situation, you can just modify something minor such as the description or summary by one letter, and then you can run the install or update command successfully.
pod update POD_NAME will update latest pod but not update Podfile.lock file.
So, you may update your Podfile with specific version of your pod e.g pod 'POD_NAME', '~> 2.9.0' and then use command pod install
Later, you can remove the specific version naming from your Podfile and can again use pod install. This will helps to keep Podfile.lock updated.

Integrate Grabkit with cocoa pods in existing project

I have integrated Grabkit in my project via adding submodules. I want to add grabkit via cocoa pods. I surfed web alot. I have created a pod file.
pod 'Grabkit', :git => 'https://github.com/pierrotsmnrd/grabKit.git'
I have downloaded latest podspec file from https://github.com/CocoaPods/Specs/blob/05def154728953519546ee0c648a82f293d02f4f/grabKit/1.4/grabKit.podspec
When I run pod install or pod update I get following error:
$ pod update
Analyzing dependencies
CocoaPods 0.29.0 is available.
Pre-downloading: `Grabkit` from `https://github.com/pierrotsmnrd/grabKit.git`
[!] No podspec found for `Grabkit` in /path-of-my-project/Pods/Grabkit/Grabkit.podspec
Please suggest !!
I'm not sure why you'd want to download the latest podspec. The specs are automatically managed by the pod command line tool and there is a clone of the entire specs repo in ~/.cocoapods. The issue here is the case. It is grabKit notice the lowercase 'g'

CocoaPods block dependency installation

I haven't found the answer to this within the Podfile docs, so I'm not sure if it's possible.
I want to install a CocoaPods project which has 3 dependencies. I add it to my Podfile:
pod 'IDMPhotoBrowser'
and run install:
$ pod install
Installing DACircularProgress (2.1.0)
…
Installing IDMPhotoBrowser (1.2)
…
Installing SVProgressHUD (0.9)
However, I have a hacked up version of SVProgressHUD in my project which contains code not in the current repo. Additionally, SVProgressHUD 0.9 is from January, and there are months of additional commits since then. I would like to use my manually added version instead.
Can I specify in my Podfile that SVProgressHUD should not be installed, so that my manually added version is used? Or do I just need to delete it by hand every time I run pod install?
Alternatives
I know I could upload my fork to github and do something like:
pod 'SVProgressHUD', :git => '<my git repo>', :commit => '<my sha>'
but I'm hoping to not need to upload code just to get Cocoapods to do what I want.
It's not so much about blocking the dependency as it is overriding it with your own. This means that CocoaPods needs to find your local copy of SVProgressHUD before it activates IDMPhotoBrowser and looks for SVProgressHUD in the master spec repo.
You can achieve the setup you want by declaring your version of SVProgressHUD first in your Podfile using a local podspec:
Your custom version needs to be in a subdirectory of your project, with a valid podspec at the root of that directory, e.g., External/SVProgressHUD/SVProgressHUD.podspec.
Update your Podfile like this:
pod 'SVProgressHUD', :path => 'External/SVProgressHUD' # this needs to be declared first
pod 'IDMPhotoBrowser' # your custom pod will be used as the dependency here
If you don't have a local podspec, you should be able to take a copy of the 0.9 version of SVProgressHUD (and if necessary modify it to compile any new code you've added).

Resources