It's not possible to merge a framework with resource into an iOS app target because the resource are not included in the app bundle.
Steps to reproduce:
-
Create an Xcode Project with iOS App Template
-
Add a Framework Target (make sure to "Embed in Application")
-
Add an Asset Catalog to Framework Target
-
Add an Color Resource (or Image Set, or any other Resource)
-
Reference the Resource in App Target (I have used a SwiftUI View)
-
Run on Device (!) to make sure everything works as expected
-
Change "Create Merged Binary (MERGED_BINARY_TYPE)" build setting of app target to "Automatic (automatic)"
-
Change app target settings to link, but not embed framework target (e.g. change from "Embed and Sign" to "Do Not Embed" in "Frameworks, Libraries and Embedded Content" section in "General" tab)
-
Run again (on Device!) and observe how the resources framework resource cannot be found anymore (using SwiftUI you will see a "No image/color named '...' in asset catalog for ..." error message in console logs)
Note:
- Everything works fine in Simulator
- Same behavior for Release and Debug configuration
- Same behavior for manual and automatic merging
- Same behavior for resources which are not bundled in Asset Catalog
- When archiving the app, an "Assets.car" file is never present (even when creating archiving for Simulator target, when "Allow archiving for Simulator" is enabled)
Reported as FB13716505 Test Project: https://github.com/iteracticman/MergeableResources/
I don’t have time today to work through all of your steps, but I have a couple of bits of feedback.
First, you wrote:
Change app target settings to link, but not embed framework target
That shouldn’t be necessary. When you use a mergeable framework in your app, you still need to embed the framework so that you get all of its resources. However, what gets embedded is a cut down framework, with all the resources but only a stub Mach-O image.
Remember that the Build Mergeable Library build setting only results in merging in release builds. So, if you changed this setting because you weren’t seeing the framework’s code getting merged in, make sure you’re not testing on a Debug build.
The other tricky part here is the involvement of asset catalogue magic. I recommend that you re-test with some code, to see if you can get that working. Once you have it working, you can then go on to explore the asset catalogue stuff.
In my case I put this simple code into my framework:
public final class Greeter {
public static func greeting() -> String {
guard let u = Bundle(for: Self.self).url(forResource: "Greeting", withExtension: "txt") else {
return "+++ URL"
}
guard let s = try? String(contentsOf: u, encoding: .utf8) else {
return "+++ string"
}
return s
}
}
along with a Greeting.txt
file. It was able to access call that code and have it fetch that file in both Debug and Release builds, and in the Release build I saw the framework’s code merged into my main app.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"