I have a module/framework written in Swift, intended to be used on iOS. When I try to include the framework in my app, I first notice some red "not found" hints in the build phases:
But, the project builds fine - the target dependency is found, so there are no compilation issues. It's just the resulting built framework - and sure enough, upon launching, I have a linker error, it can't find the image. Looking at the build log, it's looking here:
/Users/Craig/Projects/Fluffy/build/Debug-iphoneos/
Which makes sense - that's what is defined in the Build Settings for my framework:
But the copy fails, as the source framework doesn't exist:
PBXCp /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework /Users/Craig/Library/Developer/Xcode/DerivedData/MyApp-dcjfhcnyzkwzxiejuuxqlsgajreb/Build/Products/Debug-iphoneos/MyApp/Frameworks/Fluffy_iOS.framework
...
error: /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework: No such file or directory
However, looking at the build log for my framework, I see that it's actually ending up here:
/Users/Craig/Library/Developer/Xcode/DerivedData/Fluffy-fuuewsvogdkycegheyrsabkiicxc/Build/Products/Debug-iphonesimulator/Fluffy_iOS.framework
I suppose that makes sense - DerivedData has for a while now been the default location for any built products.
And when I take a look at the expected build folder, there's not much, a lot of it is old, and none of it relates to the Debug configuration:
So my questions are: Why is my framework being placed in the DerivedData
folder, when it seems to be asking in the Build Settings to be placed in the build
folder relative to the project? Are these parameters (per-configuration build products path, etc.) consulted at all?
And, what should I do to reconcile this? How can my application know to look in the right DerivedData folder for the framework, for the right configuration (debug vs. release) in a way that is extensible and will work without me having to manually specify the absolute path to it?
Okay, so I figured out how to work around this. This assumes you have workspace and you have included the framework as a project in the workspace and you are trying to build a product from another project in the workspace which includes the framework.
What you need to do is find out where the framework is being built. It's usually some crazy directory under the DeriveData
directory. Go to the Finder and find it for the configuration you just tried to build.
In the product target's General
settings, under Embedded Binaries
, drag that file into it. This should now place it in the Project Navigator
. You should also see it in the Linked Frameworks and Libraries
which was underneath Embedded Binaries
.
Go to the Project Navigator
and select the file and view it under the File Inspector
. There, change the Location
to Relative to Build Products
.
In the target's Build Settings
, for Framework Search Paths
, add $(BUILT_PRODUCTS_DIR)
and make that recursive. Delete the entry that was automatically added when you added the framework. It will be an explicit path which has the DerivedData path in it.
Do a deep clean and delete the DerivedData
directory for good measure.
Build.
You should now see the framework turn black and it should work properly.
These are slightly modified steps provided by @Mobile Ben
Assume, you have the following Xcode project structure
-YourWorkspace
--YourFramework project
--YourApp project
step 1. Clear all the targets with Cmd+Shift+K
and Cmd+Option+Shift+K
(by choosing each of them in the Scheme selector and pressing the hotkey combination)
step 2. Select YourFramework
project.
step 3. Choose a simulator and build (Cmd+B
) YourFramework
framework target
step 4: Choose Generic iOS Device
and build (Cmd+B
) YourFramework
framework target
step 5: Select YourApp
project. Press +
in Embedded Binaries
and choose the framework under YourFramework project
step 6: now locate the just added framework in Project Navigator (on the left). In File Inspector (on the right) select location Relative to build product
.
NOTE: I believe the step 6 is required b/c of some bug in Xcode. But, though, not selecting Relative to build product
by default might be a deliberate act
UPD#1: Since Xcode 8.0 (8A218a), step 6 is not needed anymore - the IDE sets Relative to Build Products
automatically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With