As the project grows, Xcode has to compile more and more code. Our code is already modularized, and there are plenty of occasions where we don't want to continuously rebuild everything. This is especially true for external frameworks. In this episode we take advantage of tuist cache to generate precompiled binaries to link with, making our builds lightning fast.
As the project grows, Xcode has to compile more and more code. Our code is already modularized, and there are plenty of occasions where we don't want to continuously rebuild everything. This is especially true for external frameworks. Before we start I'm going to upgrade our tuist version to 4.124. It's a good idea to keep your tuist version updated as it is under active development and some of these features may not exist in older versions, or you may be missing important fixes. Open up mise.toml and Change the tuist version: [tools] tuist = "4.124.1" // or latest Tuist implements a caching feature that allows you to precompile xcframeworks and link them with the project. This takes advantage of the fact that your xcode project is generated and can easily be reconfigured to link with precompiled libraries rather than compile source code. Note that this is different than the Xcode Compilation cache which is a recently supported feature in Xcode that Tuist also has support for. The cache we'll be utilizing today is called the Tuist Module Cache. To show off how this can work, let's add a handful of external libraries. In Tuist/Package.swift we'll add these: .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0"), .package(url: "https://github.com/connectrpc/connect-swift", from: "1.2.0"), .package(url: "https://github.com/newrelic/newrelic-ios-agent", from: "7.6.0"), .package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.5.2"), .package(url: "https://github.com/swiftlang/swift-syntax", from: "602.0.0") In our main Project.swift we will add a dependency on these libraries: .external(name: "Alamofire"), .external(name: "Connect"), .external(name: "NewRelic"), .external(name: "Lottie"), .external(name: "SwiftSyntax"), .external(name: "SwiftParser") When we generate the project we can now see much more source code in the left side navigator. And just for good measure we'll make sure to actually import them in our project so that Xcode doesn't try to optimize them out. When we do a build, it takes around 9 seconds on my machine. It needs to compile around 900 source files, most of which I don't need to see or debug. If we now run tuist cache it will create binaries for each of these. After running tuist cache we can generate a focused project like tuist generate StepMeter and have all the rest of the modules come in as binary frameworks. With this change our Xcode build changes to 0.1s. You can of course include more modules as source as needed by specifying them in the generate command.