How to Configure Xcode Cloud
Xcode Cloud sounds really great for us developers. At least it sounds great to me, because I’m a fan of integrated solutions that I don’t have to tinker with myself. Because they usually require additional administration as well.
Despite all the sunshine of such integrated solutions, the devil - as always - hides in the details. Because under certain circumstances, the configuration can be a bit tricky, or at least not entirely straightforward at first glance. For a smooth workflow of Xcode Cloud, the Xcode project itself, i.e. its setup, is quite important.
The actual state
The project we are working on in the company is a multiplatform project. That means there is a code base for iOS (iPhone & iPad) as well as macOS with two targets (iOS and macOS). My colleagues started it from scratch around fall 2021 and we are using SwiftUI exclusively for it (so far). I joined the project as a new member in March 2022, and it was important to me from the beginning that we were using a viable system for CI/CD. However, after initial attempts and some success with GitHub Actions, we decided to wait until WWDC and go with Xcode Cloud.
The week of WWDC, Xcode Cloud was released to everyone, and I got right to work setting it up.
Our project structure
Our project is an
.xcodeproj file. We have basically put all the code into our own Swift packages, which are located on GitHub in private repositories. They were integrated into Xcode using the "Add Local..." function.
Our project is structured as follows:
Cusstomer/ Package1/ Package2/ Package3/ OurApplication/ App/ OurApplication.xcodeproj Docs/ ...
Package3 as well as
OurApplication are located in their own private repositories on GitHub.
Using this method, Xcode automatically creates a new "Packages" group in the project navigator. Locally added Swift packages then appear in this group.
This has been working great for us so far, because all developers have the same file system structure in relation to the projects. But if such a project is loaded to Xcode Cloud, then it will certainly fail. And that's how it was for me. How would Xcode Cloud know how to get the required source code of the private Swift packages?
What I didn't know was that I can specify multiple sources for the same package in Xcode. Once locally and once via a URL, for example from GitHub. Both
https://... as well as
firstname.lastname@example.org:... URLs will be processed. The locally included package works like a "shadow reference". It covers the version that was included via URL. This way I can develop locally on the package, and after a push to the repository, Xcode Cloud recognizes the URL reference to take that for compilation. How convenient to know. 🤓
This hidden feature of Xcode was brought to my attention by Anders Bertelrud, an Apple engineer, after I asked a question about this issue in the WWDC22 Slack. He referred me to the appropriate developer documentation in his answer.
But for some reason, it still didn't work for me. I must have missed something. So I read through the above documentation again very carefully.
And... Bingo! Paragraph 3 actually describes it quite accurately.
Select the Swift package’s folder in Finder and drag it into the Project navigator.
"Drag into the Project navigator" - That was not what I was doing. I had used the Xcode function "Add Local..." as described above.
But why - and here I put the question directly to Apple - WHY??? do these two ways of including a package behave so differently? Why is there one way and the other way at all? You won't find it in any documentation, nowhere. 🙄
Well... think for a moment and re-integrate the packages. Those were my next steps:
Remove all references to the three packages from the project. Locally and via URL.
Integrate all three packages via Xcode (screenshot above) using their GitHub URL. Because they are private repositories, the
email@example.com:...URL, and not the
https://...URL must be used.
Then drag and drop all three packages from the Finder into the project navigator as described in the doc. We remember, I mentioned above that our project is an
.xcodeprojfile. Now, when dragging and dropping, Xcode asks if we want to save everything in a new workspace. Okay, that's what we want to do.
After that, Xcode should be closed and the project reopened, but this time we will use the
.xcworkspace file. Now it looks a bit different. All three packages are on the same level as our project itself now.
Now again, I pushed all to GitHub and watched Xcode Cloud.
Tattaa... Everything turned green! 🎉😃
I am curious to see how Xcode Cloud will prove itself in daily use. We must not forget that it is still in beta stage. So we can expect the one or other inconsistencies and bugs.
Once again, I would like to thank Anders Bertelrud very much for his suggestions to set it up. These WWDC Q&A sessions are really a worthwhile thing. And I'm glad Apple has opened up here, and is now offering them via Slack as well. 👍🏼
Leave a comment