Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift iOS module not being deployed to expected debug directory

Tags:

xcode

ios

swift

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:

enter image description here

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:

enter image description here

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:

enter image description here

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?

like image 425
Craig Otis Avatar asked Sep 26 '14 11:09

Craig Otis


2 Answers

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.

like image 160
Mobile Ben Avatar answered Oct 22 '22 10:10

Mobile Ben


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.

like image 26
Yevhen Dubinin Avatar answered Oct 22 '22 11:10

Yevhen Dubinin