Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift package in two targets in Xcode causes duplicate symbols

I have two frameworks in my project, each of which depend on the same Swift package (in this case RxSwift, but I don't think that's important).

To get the project to build I've had to include the same package in both targets (via the "Frameworks and Libraries" list in the target's General settings) - otherwise when I try to import the package it can't find it.

When I run my app I see warnings in the console like:

objc[79287]: Class _TtC9Alamofire18UploadTaskDelegate is implemented in both

/Users/deanWombourne/Desktop/PackageManagerTest/DerivedData/PackageManagerTest/
Build/Products/Debug-iphonesimulator/Framework1.framework/Framework1 (0x110877e00)

and

/Users/deanWombourne/Library/Developer/CoreSimulator/Devices/2319A320-1A01-4784-B85E-272FF0F999CB/
data/Containers/Bundle/Application/D40DE3EA-DD78-4241-B307-070CDAF8BFA1/PackageManagerTest.app/PackageManagerTest (0x10f9858c8).

One of the two will be used. Which one is undefined.

and, sometimes, the app crashes in the package which is duplicated.

I've tested the app by building a version without the duplicate package issue (copy/paste all code into the same target!) and it runs fine then, so this is something to do with the duplicate package issue.

So, what's my question?

Is there any way in Xcode to specify that a single package will be included in two targets, but not to just copy it twice into the executable?

I'd ideally like to specify it as a dynamic library of some sort so it's not baked into the executable at all but is loaded on demand - but any solution is welcome at this point!


EDIT

I also get this issue if I have only one framework but it shares the RxSwift package dependency with the main app target.

like image 257
deanWombourne Avatar asked Sep 25 '19 19:09

deanWombourne


1 Answers

How I resolved the issue in XCode 11 for RxSwift package:

  1. Add the RxSwift package as a dependency to your project (you probably already did it)

  2. Create a new framework target (I called it 'RxSwiftDependency'). You don't need to add any files or anything else to it. Leave it as it was created.

  3. On General tab for that additional target add the swift-package dependency in 'Frameworks and Libraries' section (see screenshot below)

  4. Add that additional target (RxSwiftDependency) to the 'Frameworks and Libraries' of the targets that need the dependency. And remove 'RxSwift' if you added it before.

  5. In .swift files of other targets that need RxSwift entities add 'import RxSwift'

  6. Embed all necessary frameworks in the final target

Screenshot1

like image 191
Aleksei Kolchanov Avatar answered Sep 23 '22 14:09

Aleksei Kolchanov