So I'm working on a large client app with lots of frameworks and modules which is is a mix of Xcode frameworks with 3rd party dependencies in CocoaPods and newer/converted SPM modules. Essentially CocoaPods is used to set the 3rd party dependencies on various Xcode frameworks, which also depend on each other via manual set dependencies, plus a bunch of SPM modules which are also manually added. It's a bit of a mess.
The problem we encountered the other day started when I added a new protocol to one of the SPM modules. Nothing special about it, all types from Foundation and the app built and ran perfectly in simulator with a Debug build.
However when we switched to building a Release build, it failed to link, logging an error indicating it could not resolve the new protocol in a number of the Xcode framework projects.
The resolutions go like this:
The Xcode app project has some manually added Xcode frameworks.
Those frameworks have manually added dependencies on a second Xcode framework.
That second framework has an SPM dependency on the module where my protocol lives.
So Xcode App -> 1st Xcode framework -> 2nd Xcode framework -> SPM module.
Now the 2nd Xcode framework directly uses my protocol from the SPM module. But the 1st Xcode framework neither uses or imports the SPM module.
Yet the error we get when building for Release is that the 1st Framework is unable to resolve the protocol from the SPM module even though it's completely oblivious to it.
My working theory is that something in the way a Release build works is insisting that when linking the 1st Xcode framework, it has to resolve the 2nd Xcode framework, which then has to resolve types from the SPM modules, but for some reason and only in a Release build, it's unable to.
So our current workaround has been to add the SPM module as a dependency to all 1st level Xcode frameworks that have the 2nd Xcode framework as a dependency. That works because when linking the 1st Xcode framework, it has a direct reference to the module even though the code never imports anything from it.
Does this should correct?
Post
Replies
Boosts
Views
Activity
We have a large multi-module project which I'm attempting to introduce SwiftMacros to in order to reduce some boilerplate. In the workspace I have 3 SPM package where I've added macros, making sure the each module only contains the macros relevant to the purpose of that module.
In the Package.swift files I've added `swift-syntax in dependencies:
dependencies: [
.package(url: "https://github.com/swiftlang/swift-syntax", from: "510.0.0"),
],
And then in a macro target:
.macro(
name: "ToolboxMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
],
path: "Sources/Macros"
),
Individually I write, debug and test those macros and the code that uses them without an issue.
However when I attempt to compile the app itself (including the packages with macros) it fails with errors on every Swift-Syntax modules like this
Prepare build
error: Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework/Versions/A/SwiftDiagnostics'
note: Target 'FlagDataMacros' (project 'FeatureFlagsMacros') has copy command from '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/PackageFrameworks/SwiftDiagnostics.framework' to '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework'
note: Target 'ToolboxMacros' (project 'Toolbox') has copy command from '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/PackageFrameworks/SwiftDiagnostics.framework' to '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework'
note: Target 'ToolboxUIMacros' (project 'ToolboxUI') has copy command from '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/PackageFrameworks/SwiftDiagnostics.framework' to '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework'
error: Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftParser.framework'
…
etc, etc
And so on for every module in Swift-syntax. Then it's followed by:
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftBasicFormat.framework'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftBasicFormat.framework/Versions/A'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftBasicFormat.framework/Versions/A/SwiftBasicFormat'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftCompilerPlugin_639CE4BF99800FCA_PackageProduct.framework'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftCompilerPlugin_639CE4BF99800FCA_PackageProduct.framework/Versions/A'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftCompilerPlugin_639CE4BF99800FCA_PackageProduct.framework/Versions/A/SwiftCompilerPlugin_639CE4BF99800FCA_PackageProduct'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework/Versions/A'
Multiple commands produce '/Users/clarkson/Library/Developer/Xcode/DerivedData/Medibank-fqrwypscprflcvfjhncnoonbjtzn/Build/Products/Debug/Frameworks/SwiftDiagnostics.framework/Versions/A/SwiftDiagnostics'
…
etc, etc
Does anyone know how I can resolve this because the only thing I can think of is to create a single macro package, however I'd rather associate the macros with their correct modules rather than creating one global macro package.
Two days into using Xcode 15 and I'm finding it quite unstable.
Firstly there are times where it just crashes. No idea why at the moment, it just goes.
Then there are the hangs. 100% CPU on one core and a completely unresponsive UI. Force Quit sees it as not responding and I have to kill it. Every time with this it's been a particular swift source code file that is causing the issue. Opening that file triggers something that hangs the UI, sometimes pretty quickly, sometimes after a few seconds.
It's always the same files too. Completely reproducible. Most sources are fine, it's just the odd one that locks up 15.
In all cases the sources compile fine. So it appears to be something in Xcode that's getting itself in knots.
We have a large project where we have some View's that are being passed data in their initialisers to setup various @State variables. Recently we added some code to one of these views and the compiler immediately failed to compile it, indicating a compilation failure on a line that had not been changed. After some work to understand the problem we distilled it down to the following examples.
Here is some original code that compiles, it sets the State variable in the init() because that matches the much bigger source this was distilled from.
struct SomeView: View {
@State var anInt: Int
init() {
anInt = 5.
}
var body: some View {
Text("Hello \(anInt)")
}
}
Now we add a Date variable and the compile fails with an error:
struct SomeView: View {
@State var anInt: Int
let date = Date() /* New variable declaration. */
init() {
anInt = 5 /* Compile fails with error: Variable 'self.anInt' used before being initialized */
}
var body: some View {
Text("Hello \(anInt)")
}
}
This obviously caused much confusion here. Now at this point we managed to fix the code by doing this:
struct SomeView: View {
@State var anInt: Int
let date = Date() /* New variable declaration. */
init() {
_anInt = State(initialValue: 5)
}
var body: some View {
Text("Hello \(anInt)")
}
}
However it doesn't explain why the compilation failed in the first place. Nor is it great as it feels like we're going backwards when it's perfectly ok to just set anInt = 5 with the latest compilers.
We'd like, if possible, for a Swift compiler engineer to take a look and give us an explanation (so we can better understand the issue) and possible improve the error reporting in future compiler releases. Currently we think it's something to do with Date being a ReferenceConvertable as swapping in other ReferenceConvertable's also trigger the same compiler error.
I have a project where I've been using test plans for the past month (Xcode 13.4.1).
Then today they just stopped being available. I was checking one of my schemes and noticed that it didn't have the test plan associated with it. So I went to the Build section and clicked the Add Target + button, but my Test plan files didn't show up. So I went to the Test section and it was showing the test target, not the plan. So I removed the target and hit the Add test target + button and again none of my test plans appeared. The test navigator is no longer showing the test plan above the tests.
So I looked in Product - Test Plan and the only enabled menu item was to Create a Test plan. So I tried that and created and brand new test plan. When back to the scheme and still could not add it to the scheme. Nor could I get it to display at the top of the test target.
I checked the git changes and it showed a bunch of new schemes which I hadn't created and all my schemes being changed back to from .
Yet when I go back to the scheme I'm not offered any option to enable test plans again. And the Product - Test Plan menu items remain disabled.
I've tried clearing derived, restarting Xcode, wiping all my test plans and rebuilding but nothing I do is enabling the test plans again.
How do I fix this?
I work with a number of enterprise clients and one thing we often do is have various frameworks that are optional depending on what type of build we are doing. A common example being to include a framework that contains an embedded server for testing, demo or debugging purposes.
Prior to SPM we would link those frameworks as "Optional" and run a script phase after the build that removed them from the Frameworks directory of the app if it was a "Release" build.
Now I have an Xcode project that includes a number of SPM package, one of which is an embedded server which in turns references several other packages I'd like to exclude form a "Release" build.
But I cannot figure out how to do this. Can I make the inclusion of a package optional? Or somehow remove it after linking?
In Swift I can write #if canImport(MockServer) but I cannot see how to actually make MockServer an optional include.
Any ideas?
I have a SPM framework project that includes both Swift code and JSON file resources.
With a package file that looks like this:
let package = Package(
name: "MyTestData",
products: [
.library(
name: "MyTestData",
targets: [
"MyTestData",
]
),
],
targets: [
.target(
name: "MyTestData",
dependencies: [],
path: "Sources",
sources: ["ios"],
resources: [
.copy("payloads"),
.copy("snippets"),
]
),
]
)
Now all the SPM packages resolve correctly and the code compiles and works, yet the Xcode workspace is showing errors like this:
Now payloads and snippets are not projects and I've tried all sorts of variations of path, sources, exclude, resource in my Package file and either I get the errors and everything works, or the errors disappear and the project doesn't work. I don't know what the issue is and there's nothing in the resolving or build logs.
Does anyone know what might be the problem here?
HI all, just wondering if anyone else has this. I have the iOS16 and I've just noticed that if I try to download an app from the App Store, it just sits there with the circular waiting indicator spinning forever. The download never starts.
Just me or anyone else?
Hello everyone. The project I am working on is shifting from using CocoaPods to SPM and there is one "wrinkle" I'd like some advice on. The project has several framework projects containing code as well as the main app project. All of these make use of code generators (RSwift, Sourcery) at some point and these need to be run before the main build starts.
The problem is that SPM builds do not support the concept of adding script phases so there appears to be no easy way to incorporate these shell tools into the builds. Particularly in the framework projects which are pure SPM packages and therefore do not have your typical project files and build phases.
My question is - how to deal with shell based build phases in an SPM world?
Currently we are adding these phases in the main app's build. However they are not run before the builds of the SPM dependencies so effectively we have to run the build twice to ensure the code is up to date.
I have a new SwiftUI project I'm working with on my M1Pro. The project is a simple single screen app and I selected new project app when I created it. Selecting to create unit test targets as well.
The app builds and runs. The UI tests build and run successfully.
I then attempted to create a simple unit test and run it. However it's not compiling. The apps module name is "PointsMasterII" and when try to add import PointsMasterII to the unit test, I get the error:
Could not find module 'PointsMasterII' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator, at: /Users/derekclarkson/Library/Developer/Xcode/DerivedData/PointsMasterII-ahjymfmhybwxvxakiwljcqfzmqea/Index/Build/Products/Debug-iphonesimulator/PointsMasterII.swiftmodule
I also had this is the test class:
func testPoints() {
let calc = Calculator()
}
And when I checked the log of the build I saw
Undefined symbols for architecture arm64:
"type metadata accessor for PointsMasterII.Calculator", referenced from:
Tests_iOS.CalculatorTests.testPoints() -> () in CalculatorTests.o
"PointsMasterII.Calculator.__allocating_init() -> PointsMasterII.Calculator", referenced from:
Tests_iOS.CalculatorTests.testPoints() -> () in CalculatorTests.o
ld: symbol(s) not found for architecture arm64
I don't know how to fix this. I would have expected it to work as the unit test target has the PointsMasterII app as a dependency (setup by Xcode) and the app and UI tests run fine.
Any pointers as to what to look at?
Hello everyone. I'm in an interesting situation where I'm writing a new version of an app from the ground up because the previous (old buggy) app was written using a technology that's out of date and no-one here understands.
Because the app has a local database we want to load into the new app we are keeping the original bundle id. The theory being that the new app overwrite's the old app on a user's device and reads its data.
The problem I have is that it appears that the old app had location updates turned on and was (possibly) consuming battery as a result. In the new app I don't think we need this capability any more and I also want to add the "Background Fetch" or "Background Processing" capability to schedule so local notifications.
My question is can I change the capabilities of an update to an app in the App Store, or am I restricted to the capabilities of the original app?
Big Sur is constantly dropping my wifi connection even though I'm less than 10 feet from the router. Sometimes it drops it after only a few seconds, sometimes I can get 20 or 30 seconds and sometimes it shows as connected but I can get any data.
Typically this will go on for 10 or 20 minutes then for some reason it appears to stabilise and stay connected.
It also fails to connect every time I wake the machine.
Anyone else experiencing this?