I want to know, is it possible to build Pods only once? Because building them each time without any changes takes too much time.
Is there any solution for building Pods only once and reducing build time with it?
Xcode should be caching some build information in derived data after the first build. However, other than that, there's not much to be done. I would suggest a faster computer or less dependencies :)
If this is a real pain in the neck and you don't mind getting rid of cocoa pods, you can alway import the compiled frameworks manually. That would pretty much get rid of any build lag from your pods, but you'd also have a hard time keeping the pods up to date.
You could try precompiling Pods with https://github.com/leavez/cocoapods-binary as described here https://guides.cocoapods.org/plugins/pre-compiling-dependencies.html
You append binary => true in your podfile to the pods you want to precompile, which switches them to compile frameworks.
plugin 'cocoapods-binary'
use_frameworks!
target "HP" do
pod "ExpectoPatronum", :binary => true
end
But I find XCode does a pretty good job of caching what's needed.
Related
I often use pods in my Obj-C and Swift projects and quite often need to tweak a pod for my use-cases. I noted recently that my edits were having no effect, that the original bits were being used, and there were many times I was stumped at a situation that I thought my editing corrected, only to realize the compiled bits did not include my latest brilliant hack.
Then I discovered that simply cleaning the build folder (shift-cmd-K) will reset everything and the next build incorporates my edits. I now do this as a matter of regular business with each pod edit, but wondered if there was a simpler way to set a pod to be included in each rebuild.
Editing pods is not ideal, simply because all your changes will be removed after the next pod update.
The best way here would be to fork the pod, modify it and use your own version instead.
I just noticed cocoapods with Swift increases build size, however when I use same libraries manually then build size is normal.
I created a blank project with some pods and the build size goes to the 10MB and .app file is around 40MB.
I also notices that my .app file contains all my cocoapods frameworks
(around 37MB) by viewing "Package content".
My podfile having these pods
pod 'Alamofire', '~> 4.4'
pod 'SwiftyJSON'
pod 'IQKeyboardManagerSwift'
pod 'ActionSheetPicker-3.0'
pod 'Kingfisher'
pod 'JKNotificationPanel'
My questions are
why my .app file contains all framework, I guess it happens only with Swift and cocoapod (Correct me if I am wrong) ?
How can we reduce the size of build by using cocoapods with Swift
Thanks in advance
If you use the libraries as static libraries, the linker can exclude the parts of them that you don't use from the build. The same is not true for frameworks. So if you just made an app with those libraries and didn't use them, they won't be included at all, so it's not a fair comparison.
When you ask why your app contains all frameworks I assume you mean the ones for the swift runtime and not the dependencies you explicitly asked for in cocoapods. All swift apps have the runtime bundled into them, at least until the runtime becomes stable enough (changes very often nowadays), and then the phone OS will contain a few versions of it and we won't have to include it in the app.
Also, don't get terrified by the app size. The actual size of the app the user downloads is much smaller. You can see it in iTunesConnect's activity tab and then picking your build, once you've uploaded it there obviously. I've seen apps that upload as 120MB or so to iTunesConnect and then the final download to the user is 20 to 30MB.
Edit after getting more info:
You said you are comparing dragging the sources of libraries into your project vs cocoapods, and there's a clear difference here: if you add the source files of the library it's not the same as adding the compiled framework for the library. If you add the sources, a lot of the unused stuff will be optimized out, thus affecting the size. Example of this is when a library includes a category that the library itself is not using. Unless some linker flags are used, the category is optimized out and it doesn't work on the app using the library (you can search for all_load if you want more info). When using frameworks nothing is optimized out, but this is not happening due to Cocoapods. You can use frameworks without Cocoapods, and you should get exactly the same results regarding size.
Edit 2:
It looks like swift 5 might achieve ABI stability! We might be able to choose swift for apps that need to be as small as possible now with it!
I have an Xcode project (objective c, Xcode 8.2.1).
Whenever I do "Clean build" and build again, it takes a very long time. I started to look into the reason for this and I noticed that all my pod source files are being compiled twice (which I guess doubles the compile time).
At the top of Xcode, you can see the status of the build as it progresses
You can see in the screenshot above that Xcode is compiling 142 source files for the Realm pod, but it only has 71 source files. All my other pods have the same issue.
I tested creating a new xcode project and adding pods, and then I don't experience the same problem as in this project.
#Bdash suggested that I might be having the build setting "Build Active Architecture Only" set to "No", but I have checked this and it is set to "Yes".
Any ideas on what could be the problem here?
This tends to happen when you have custom names for your build configurations. That is, if you have a name other than Debug or Release, CocoaPods will treat such configurations as release ones. Besides other things, this means enabling optimizations and setting the Build Active Architecture Only flag for those Pods to YES. Both options will hinder compilation times for Debug configurations.
To fix it you have to specify which configurations are Debug ones. Following the docs, you have to change your Podfile so it looks something like this:
project 'MyApp', 'MyAppRelease' => :release, 'MyAppDebug' => :debug
Unfortunately, Realm is a large project with a significant number of C++ and Objective-C++ source files, and generally takes a while to compile (especially after cleaning the build folder). Exactly how long Realm takes to build depends on what sort of computer Xcode is running on, but the numbers you provided don't seem to be unreasonable for older hardware.
So i'm using these two pods in my project:
pod 'Google/SignIn'
pod 'MSOutlook-SDK-iOS'
To my delight, they both have dependencies that use a Core.h file. I believe i am running into issues that cause a File Not Found for one of the pods because it is looking for a file in the wrong header!
I guess I can make the import explicit, aka changing:
core.h/NSArray+Utils.h
to
orc/core.h/NSArray+Utils.h
But I don't want to do that bc of two reasons:
These pods get updated from time to time, and might introduce new files/overwrite existing changes
There are about 350 files I need to do that to.
Any ideas on how to resolve this? Possibly some renaming or settings change?
Thanks!
This purported error has claimed to been fixed in Cocoapods v1.0 and above.
From github:
"This ought to be fixed in CocoaPods 1.0 if you use bracket imports."
I'm working on pods development for an iOS dev team (on private repo). My low-level C/Obj-C core pod contains a static library with some headers and is used as dependency in other pods (pushed with --use-libraries).
Now that the iOS team wants to integrate Swift pods, they had to add the use_framework! option in the Podfile of their projects. Of course, they obtained the following error during pod install :
The 'XXX' target has transitive dependencies that include static
binaries
I spent half a day on the web looking for a way to make my pods compatible with the use_framework! option, in vain. This is very frustrating, as Google Services pods are proofs that it's possible to bypass this problem in a clean way (not with the verify_no_static_framework_transitive_dependencies trick) : the main pod and almost all its dependencies contain static libraries, and everything works perfectly along with Swift pods. Exemple with Google/SignIn which depends on Google/Core (vendored_libraries: Libraries/libGGLCore.a) and GoogleSignIn (vendored_libraries: Libraries/libSignIn.a).
Any idea of what I can do to make my pods compatible with the use_framework! option ?
Thank you all,
Cheers,
Tom
I think I found a hack for my problem. This is quite weird, but I'd say it's clean enough to use it in production ;)
I found it here. The idea is simply to include a source file (even an empty one) in your source_files list inside your podspec.
Basically, the source section of my podspec looks like this :
s.source_files = "myLib/Empty.m", "myLib/Headers/*.h"
s.vendored_libraries = "myLib/myLib.a"
The only modification I made is to add "myLib/Empty.m" in the source files (Empty.m is strictly empty). Without it, I systematically have the transitive dependencies error when I pod install. With it, pod install works fine. It worked for me with both Cocoapods 0.0.39 and 1.0.0.beta.4.
Well, looks like it's a not so dirty solution, but I'm not sure it'll work in every case. And it's no good news about the cleanliness of Cocoapods...
As I mentionned in comments earlier, Google seems to have found a cleaner solution. So if anybody have an idea of the real clean solution, please share !
Cheers,
Tom
PS : I think I'll name the file DirtyCocoapodHack.m instead of Empty.m, sure they'll love it in the dev team ;)