Skip to content

Commit

Permalink
[Release Tooling] Consistent approach to resources when building on X…
Browse files Browse the repository at this point in the history
…code 15 (#12821)
  • Loading branch information
ncooke3 authored Apr 23, 2024
1 parent 14178e2 commit ee81927
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ + (NSBundle *)getViewResourceBundle {
NSBundle *containingBundle;
NSURL *bundleURL;
// The containing bundle is different whether FIAM is statically or dynamically linked.
for (containingBundle in @[ [NSBundle mainBundle], [NSBundle bundleForClass:myClass] ]) {
for (containingBundle in @[
// Statically linked.
[NSBundle mainBundle],
// Dynamically linked.
[NSBundle bundleForClass:myClass],
// Embedded static framework (zip distribution).
[NSBundle bundleWithURL:[NSBundle.mainBundle.bundleURL
URLByAppendingPathComponent:
@"Frameworks/FirebaseInAppMessaging.framework"]]
]) {
bundleURL = [containingBundle URLForResource:bundledResource withExtension:@"bundle"];
if (bundleURL != nil) break;
}
Expand Down
61 changes: 27 additions & 34 deletions ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,33 @@ struct FrameworkBuilder {
platform == .catalyst || platform == .macOS ? "Resources" : ""
)
.resolvingSymlinksInPath()
processPrivacyManifests(fileManager, frameworkPath, resourceDir)

// Move resource bundles into the platform framework.
do {
try fileManager.contentsOfDirectory(
at: frameworkPath.deletingLastPathComponent(),
includingPropertiesForKeys: nil
)
.filter { $0.pathExtension == "bundle" }
// Bundles are moved rather than copied to prevent them from being
// packaged in a `Resources` directory at the root of the xcframework.
.forEach {
// Delete `gRPCCertificates-Cpp.bundle` since it is not needed (#9184).
guard $0.lastPathComponent != "gRPCCertificates-Cpp.bundle" else {
try fileManager.removeItem(at: $0)
return
}

try fileManager.moveItem(
at: $0,
to: resourceDir.appendingPathComponent($0.lastPathComponent)
)
}
} catch {
fatalError(
"Could not move resources for framework \(frameworkPath), platform \(platform). Error: \(error)"
)
}

// Use the appropriate moduleMaps
packageModuleMaps(inFrameworks: [frameworkPath],
Expand All @@ -663,39 +689,6 @@ struct FrameworkBuilder {
}
}

/// Process privacy manifests.
///
/// Move any privacy manifest-containing resource bundles into the platform framework.
func processPrivacyManifests(_ fileManager: FileManager,
_ frameworkPath: URL,
_ platformFrameworkDir: URL) {
try? fileManager.contentsOfDirectory(
at: frameworkPath.deletingLastPathComponent(),
includingPropertiesForKeys: nil
)
.filter { $0.pathExtension == "bundle" }
// TODO(ncooke3): Once the zip is built with Xcode 15, the following
// `filter` can be removed. The following block exists to preserve
// how resources (e.g. like FIAM's) are packaged for use in Xcode 14.
.filter { bundleURL in
let dirEnum = fileManager.enumerator(atPath: bundleURL.path)
var containsPrivacyManifest = false
while let relativeFilePath = dirEnum?.nextObject() as? String {
if relativeFilePath.hasSuffix("PrivacyInfo.xcprivacy") {
containsPrivacyManifest = true
break
}
}
return containsPrivacyManifest
}
// Bundles are moved rather than copied to prevent them from being
// packaged in a `Resources` directory at the root of the xcframework.
.forEach { try! fileManager.moveItem(
at: $0,
to: platformFrameworkDir.appendingPathComponent($0.lastPathComponent)
) }
}

/// Package the built frameworks into an XCFramework.
/// - Parameter withName: The framework name.
/// - Parameter frameworks: The grouped frameworks.
Expand Down
17 changes: 6 additions & 11 deletions ReleaseTooling/Template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ To integrate a Firebase SDK with your app:
**Embed & Sign**. This step will enable privacy manifests to be picked up by
Xcode's tooling.

8. If the SDK has resources, go into the Resources folders, which will be in
the SDK folder. Drag all of those resources into the Project Navigator, just
like the frameworks, again making sure that the target you want to add these
resources to has a checkmark next to it, and that you've selected "Copy items
if needed".
9. Add the `-ObjC` flag to **Other Linker Settings**:
8. Add the `-ObjC` flag to **Other Linker Settings**:

a. In your project settings, open the **Settings** panel for your target.

Expand All @@ -63,7 +58,7 @@ To integrate a Firebase SDK with your app:

c. Double-click the setting, click the '+' button, and add `-ObjC`

10. Add the `-lc++` flag to **Other Linker Settings**:
9. Add the `-lc++` flag to **Other Linker Settings**:

a. In your project settings, open the **Settings** panel for your target.

Expand All @@ -72,21 +67,21 @@ To integrate a Firebase SDK with your app:

c. Double-click the setting, click the '+' button, and add `-lc++`

11. Drag the `Firebase.h` header in this directory into your project. This will
10. Drag the `Firebase.h` header in this directory into your project. This will
allow you to `#import "Firebase.h"` and start using any Firebase SDK that you
have.
12. Drag `module.modulemap` into your project and update the
11. Drag `module.modulemap` into your project and update the
"User Header Search Paths" in your project's Build Settings to include the
directory that contains the added module map.
13. If your app does not include any Swift implementation, you may need to add
12. If your app does not include any Swift implementation, you may need to add
a dummy Swift file to the app to prevent Swift system library missing
symbol linker errors. See
https://forums.swift.org/t/using-binary-swift-sdks-from-non-swift-apps/55989.

> ⚠ If prompted with the option to create a corresponding bridging header
> for the new Swift file, select **Don't create**.
14. You're done! Build your target and start using Firebase.
13. You're done! Build your target and start using Firebase.

If you want to add another SDK, repeat the steps above with the xcframeworks for
the new SDK. You only need to add each framework once, so if you've already
Expand Down

0 comments on commit ee81927

Please sign in to comment.