`xcodebuild archive` always performs a clean build - ios

Every time I run xcodebuild ...params... archive it performs a clean build without reusing the cache from a previous build.
While I understand the motivation behind it, it has serious consequences on my CI build times because I generate an IPA for every push. Since my workspace has a Pods project (unlikely to change between commits) and an App project (changing all the time) I'm looking for a way to cache the Pods compilation phase somehow – which xcodebuild archive doesn't seem to allow.
Is there a way to force using the cache when archiving? Is there any other way to cache the archived version of Pods?

Related

tuist cache not taken into account when generating project file

I am trying the caching features of tuist (https://tuist.io) using one of the demos provided on Github, the app_with_spm_dependencies (https://github.com/tuist/tuist/tree/main/projects/tuist/fixtures/app_with_spm_dependencies). I was trying to see the power of caching dependencies using tuist. My approach was running the commands tuist fetch and I got here a warning about some watch target, but it shouldn't invalidate the iOS simulator targets, tuist cache warm, and finally tuist generate. I didn't see any changes in the build times. Checking the ~/.tuist/Cache/BuildCache shows an empty folder. The command tuist cache print-hashes outputs a list of hashes of the targets and external dependencies of this demo project, therefore I can assume some hashes were created. But where is the cache stored in this case? Why is the cache not being used on the tuist generated project file in Xcode 14?
I saw the compile steps for each dependency so I am sure everything is being built from scratch.
This is all down to expectations. tuist cache is nothing more than what a clean build on the Xcode project would do: download dependencies into your Build folder and compile them to be used by your code. Each cleancommand erases the Build folder, which in turn results in an empty cache. So, it turns out that the caching feature, in practice, would be the same as keeping the Build folder intact.

xcodebuild default build path

I'm trying to make a FAT framework following this guide
What I'd like to understand is the xcodebuild build path. Based on that tutorial, this is created at the beginning:
BUILD_PATH="${SRCROOT}/build"
Now when I make a build, the builds for Release-iphoneos and Release-iphonesimulator go into that build folder. Is this a predefined variable that can be set to tell Xcode where your builds can go? Because based on this other tutorial: BUILD_DIR gets passed to xcodebuild.
I was wondering what the difference is here and how Xcode handles these arguments.
How does setting this directory work with DerivedData?
Also on the topics of building, does Xcode cache builds? Sometimes after I build and do a ls -al on my frameworks, they don't have current timestamps. But once I delete the build directory, it seems to force Xcode to build again and then I get "fresh" frameworks created. Is Xcode caching the build and not replacing the build? Is there a way to force it?

Slow compile times with react-native iOS app

I am currently working on a react-native iOS app. While developing I noticed that the compile times for the app are really slow. I got a CI hooked up which roughly does the following:
clean git checkout of the applications workspace
run unit tests
run UI tests build the app
Since this is a clean checkout the app always recompiles all of the react static libraries which come with the React.xcodeproj like libyoga.a, libReact.a, etc. This means that a clean CI build roughly takes ~8min only to build all of the react dependencies (~4min * 2 because the UI test target rebuilds React again).
I wondered whether it would be possible to speed up the compile times. I came up with the following idea but need your advice to tell me if it would work or if I am on the wrong track.
Compile all static libraries for iphoneos and iphonesimulator
Put them together in a single file via lipo
Move them to a folder
Put that folder into version control
Link the libraries in that folder into the Xcode project
This way it would only be necessary to build a new set of static libraries if I update the react-native version in the package.json, right ?
Another idea which came to my mind is to build a dynamic framework of react-native. The framework could be build only once and then added to the application via carthage or manually. The dynamic framework would link all the react static libraries and add the correct headers to the header search paths.
Does anyone can give me a hint if this could work or has an idea how to improve the build architecture in order to speed up the compile time ?
Check these two checkbox
1 Show environment variables in build log
2 Run script only when installing
but when you run first time then uncheck it because this load script for first time otherwise you can not open get loading script in packager.

How to use iOS Carthage with TeamCity?

I need to up TeamCity CI/CD for my iOS project. I'm using Carthage for dependency management.
I understood that performing carthage update for each build is a bad idea. A build-agent will be rebuilding frameworks for every new build. It's very time-consuming operation.
Is there any approach for the caching my dependencies for speedup a build?
Possible approach would be setting up a separate build configuration (e.g.,"Producer") that executes carthage update (whenever needed), then uploads zipped Carthage/Build to build server. Other build configurations for your project should have an artifact dependency on "Producer" and fetch binaries back to Carthage/Build

How to force XCode 4 to always update resources?

I am adding resources (lots of .pngs and other) to my iPhone project dragging the folder to it and choosing "Create Folder references for any added Folder", to retain the folder structure.
They are correctly added to the Copy Resources build phase.
Problem is, I am wasting A LOT of time because when I create/delete/update a new resource, it will often ignore changed files and stick with the older version.
Looks like it tries to only updates resources when they are changed, but it fails to see the changes.
In the simulator it was possible to manually update the files in the .app, but when working on the device it will complain that the code sign of some resources has changed!
The only reliable way I've found to force it to update everything is deleting the build products, the app and the device app some times, until it finally decides to forget about the old version, but doing this for each resource change is wasting me an insane amount of time (game content changes more than often).
So, in short: how do I force XCode to disable "versioning" and to just scrap all the resources and copy them all each time?
Thanks!
EDIT: I have found that deleting the .app folder built in "build" folder always forces XCode to add new files...
I still have no clue on where it keeps the old files when I delete that folder, but this is for the better as it only copies new resources as intended.
So a simple script like
rm -rf "$CODESIGNING_FOLDER_PATH"
Does the trick of deleting the folder at each build...
Unfortunately, XCode apparently runs the codesigning BEFORE anything in the Build Phases tab is executed, so it updates the old target, the script deletes the old target, and then it crashes complaining that no Code Signing Resources were found.
So... I have to stick with manually deleting the file, or is there a way to run a script before code signing?
I had this kind of issue as well, about files not getting updated when I built my project (A PhoneGap project, but that should not matter).
What I did, was add this to the Build Phase of my project:
find "${PROJECT_DIR}/www/." -exec touch -cm {} \;
That will make sure the files are being picked up as updated when XCode builds the project. Of course, you should modify the command to your needs - my needs were to update the www folder on build, as I am editing my files using Visual Studio, running in a VM.
Ok, I finally found a (somewhat ugly) workaround against this.
In you project, create two aggregate targets, say Clean Build and Cleaner.
In Cleaner, add a "Run Script" Phase with rm -rf "$CODESIGNING_FOLDER_PATH" that will purge the temporary app from the build folder.
In Clean Build, add first Cleaner, and then your normal app target to the Target Dependencies.
Select Clean Build from the run list, then Edit Scheme and set your app target as the executable. Hit run, and it should work :)
You might want to use the Clean option under the Product menu (or hold down shift and command and press K) after you update a resource and before you build the updated app. I have noticed that this has helped me out at times when I update a resource or a user-defined build setting.

Resources