akaffenberger / firebase-ios-sdk-xcframeworks

A small mirror for https://github.com/firebase/firebase-ios-sdk, to add support for binary (xcframework) distribution with swift package manager.
MIT License
134 stars 32 forks source link

InAppMessaging bundle is missing #23

Closed michalciurus closed 2 years ago

michalciurus commented 2 years ago

8.15.0 - [Firebase/InAppMessaging][I-IAM400009] Display ran into error for message 3978956120715808093: Error Domain=com.firebase.inappmessaging.display Code=1 "(null)" UserInfo={message=resource bundle is missing}

Screenshot 2022-04-26 at 12 30 27

I can't get the in app messages to work.

How are .bundles working with SPM and Firebase?

Firebase seems to be using, for getting the resources for InAppMessaging

+ (NSArray *)relevantBundles {
  return @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ];
}

Correct me if I'm wrong: SPM puts all the resources into the main app bundle, but mainBundle called from .xcframework won't be the app bundle, it'll be the framework bundle, hence it can't find the needed resources. That's as far as I've gone with my investigation.

I'm trying to understand how to fix this issue as we really enjoy using this mirror. Could it have regressed? Or maybe I configured something incorrectly.

michalciurus commented 2 years ago
RESOURCE_PATH="${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk-xcframeworks/Sources/FirebaseInAppMessaging/Resources/"

FILENAME_IN_BUNDLE=InAppMessagingDisplayResources.bundle

BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}

rm -R "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"

if [ "$CONFIGURATION" == "Debug" ]; then
    cp -R "$RESOURCE_PATH/$FILENAME_IN_BUNDLE" "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
else
    cp -R "$RESOURCE_PATH/$FILENAME_IN_BUNDLE" "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
fi

I added this run script to fix the problem.

akaffenberger commented 2 years ago

Thank you for calling this out @michalciurus!

From what I can gather, you more or less found the source of the issue.

The framework is searching for InAppMessagingDisplayResources.bundle inside the main bundle. However, SPM creates a bundle per target inside the main bundle, so the actual path ends up being Firebase_FirebaseInAppMessagingTarget.bundle/InAppMessagingDisplayResources.bundle.

Apple recommends using Bundle.module when searching for resources from within an SPM framework. I haven't tested this, but the ObjC equivalent should be something like:

NSBundle *bundle = [NSBundle bundleWithURL: [SWIFTPM_MODULE_BUNDLE urlForResource:@"InAppMessagingDisplayResources" withExtension:@"bundle"]];

I will try to fork the firebase-ios-sdk this weekend and test this out, but for now I'd say your script is a decent workaround.

akaffenberger commented 2 years ago

Follow up -- unfortunately because it's a pre-built binary, Bundle.module is not available. As as a binaryTarget(), the framework gets embedded statically inside the main bundle. In short, there is no way for it to find the resources without the exact path being hard-coded programmatically, which isn't a possibility for us since this is a wrapper project.

The solutions as I see it:

  1. Use a build script as you currently have, except modify it to iterate over each Firebase_Firebase<...>.bundle and move the contained resources directly into the main bundle.
  2. Remove all resources from the Package.swift file, and update the readme to include an extra installation step, which would be to manually drag and drop any resource from the swift package into the xcode project.

I think 2 is the safer solution, since it doesn't rely on names/file structures which may change.

In the meantime, I created a SwiftPM pitch to allow for including resources directly in the main bundle, maybe it will get some traction: https://forums.swift.org/t/swiftpm-binary-target-resource-bundles/57178

akaffenberger commented 2 years ago

As per above discussion, I made the following changes:

PR: https://github.com/akaffenberger/firebase-ios-sdk-xcframeworks/pull/25

michalciurus commented 2 years ago

Thank you @akaffenberger for such a swifty turnaround! Me and our team really appreciate the work you're doing.