firebase-ios-sdk
firebase-ios-sdk copied to clipboard
Make FirebaseAnalytics available for watchOS, which build runtime error
Feature proposal
- Firebase Component: Analytics
A bit of context first: I have create a Swift Package for my app for all my cloud API, so that it can be shared among apps (macOS, iOS, watchOS, tvOS). Though SPM offers the possibility to make a target dependency conditional to the platform, this condition is only checked after the dependency has been resolved for this platform, which pose a problem for FirebaseAnalytics, has there's no watchOS build. So when configuring my package, I end up with a build error, though for the target I have a condition the dependency to FirebaseAnalytics only for iOS and macOS.
My request is the following one: instead of not providing Firebase Analytics for watchOS, make it available, but add an error at build time when the OS is watchOS:
#if os(watchOS)
#error FirebaseAnalytics is not supported for watchOS <some ref to the page where we can see which API is supported on which platform>
#endif
Typically FirebaseFirestore does the same. When building on watchOS, it gives an error (which is not actually perfect) about storage not been clearly identified on watchOS.
That way, we can still build a single API, even if for certain OS the FirebaseAnalytics API is ignored, until a day where it becomes available for watchOS (if it ever make sense, probably not).
Note: This feature request could be extended to all API for each of their unsupported platform. Please not that for each of these API, if they depend on other API, conditions should be added, as SPM resolve each dependency dependencies as well, before considering conditions.
I found a few problems with this issue:
- I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
- This issue does not seem to follow the issue template. Make sure you provide all the required information.
@gpfister Thank you for filling the request, can you share with me your Package.swift file setup? You can obscure the part unrelated to Firebase or you can send directly to my email at chliang at google.com
@chliangGoogle Sure, here's an example:
import PackageDescription
let package = Package(
name: "MyCloudKit",
platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8)],
products: [
.library(
name: "MyCloudAnalytics",
targets: ["MyCloudAnalytics"]
),
.library(
name: "MyCloudAuth",
targets: ["MyCloudAuth"]
),
.library(
name: "MyCloudCore",
targets: ["MyCloudCore"]
),
.library(
name: "MyCloudModel",
targets: ["MyCloudModel"]
),
.library(
name: "MyCloudServices",
targets: ["MyCloudServices"]
)
],
dependencies: [
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "9.2.0")),
],
targets: [
.target(
name: "MyCloudAnalytics",
dependencies: [
.product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
.product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
]
),
.target(
name: "MyCloudAuth",
dependencies: [
.target(name: "OSKCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
.target(name: "OSKCloudModel"),
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
]
),
.target(
name: "MyCloudCore",
dependencies: [
.product(name: "FirebaseAppCheck", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
.product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
.product(name: "FirebaseStorage", package: "firebase-ios-sdk")
]
),
.target(
name: "MyCloudModel",
dependencies: [
.product(name: "FirebaseFirestoreSwift", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
]
),
.target(
name: "MyCloudServices",
dependencies: [
.target(name: "MyCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
.target(name: "MyCloudModel"),
.product(name: "FirebaseAnalytics", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
.product(name: "FirebaseStorage", package: "firebase-ios-sdk")
]
),
]
)
The MyCloudAuth
is the one that you can use as example: the idea would be that on iOS there would be some analytics, and on watchOS there would be only the FirebaseAuth.
For reference, I have open an issue on Apple/Swift repo. However, while it should very likely be fixed there (I don't understand why it tries to eval the dependency, though it doesn't meet the conditions), the solution I'm proposing here is more like to be added in a timely manner.
Thank in advance for your support.
@gpfister You mean Firestore works as expected right: It will let you build with an error, which is not like Analytics.
@chliangGoogle Yes. It seems that before considering the condition, SPM will check if the dependency is available for the arch you are building for. So in the example: FirebaseFirestore is ignored properly (if the conditions was removed, it would try to build it for warchOS, but an error is raised regarding local storage), however for FirebaseAnalytics, it fails even with the conditions, as there is no FirebaseAnalytics for watchOS arch.
@gpfister We took a close look at and realize we are not able to provide a walk-around in our infrastructure at the moment. We will closely monitor the issue in Apple/Swift repo and thank you for filing it. Please upvote if anyone runs into the same issue.
@chliangGoogle - @gpfister has responded to the issue, and has a suggestion for firebase to workaround
Thoughts?
Xcode 14.3 has this release note:
Fixed: Conditional target dependencies ([SE-0273](https://github.com/apple/swift-evolution/blob/main/proposals/0273-swiftpm-conditional-target-dependencies.md)) in packages are now correctly applied to binary targets and leads to top-level targets being filtered out from builds of root packages. (85762201)
Does it address this issue?
@paulb777, sorry for getting back to you a bit late. I did some testing after using conditions in target dependencies and I was able to build the code using Xcode 14.3 (Version 14.3 beta 2 (14E5207e)). It looks like this is going to be solved.
Shall I close the issue or wait the final release of Xcode 14.3.
For those that are interested, here's how it looks like:
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "CloudKit",
platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8)],
products: [
.library(
name: "CloudAnalytics",
targets: ["CloudAnalytics"]
),
.library(
name: "CloudAuth",
targets: ["CloudAuth"]
),
.library(
name: "CloudCore",
targets: ["CloudCore"]
),
.library(
name: "CloudModel",
targets: ["CloudModel"]
),
.library(
name: "CloudServices",
targets: ["CloudServices"]
),
],
dependencies: [
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "10.2.0")),
],
targets: [
.target(
name: "CloudAnalytics",
dependencies: [
.product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
.product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
]
),
.target(
name: "CloudAuth",
dependencies: [
.target(name: "CloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
.target(name: "CloudModel"),
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
]
),
.target(
name: "CloudCore",
dependencies: [
.product(name: "FirebaseAppCheck", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
.product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
.product(name: "FirebaseStorage", package: "firebase-ios-sdk"),
]
),
.target(
name: "CloudModel",
dependencies: [
.product(name: "FirebaseFirestoreSwift", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
]
),
.target(
name: "CloudServices",
dependencies: [
.target(name: "CloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
.target(name: "CloudModel"),
.product(name: "FirebaseAnalytics", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseFirestore", package: "firebase-ios-sdk"),
.product(name: "FirebaseFunctions", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
.product(name: "FirebaseStorage", package: "firebase-ios-sdk"),
]
),
.testTarget(
name: "CloudKitTests",
dependencies: [
"CloudModel",
"CloudServices",
]
),
]
)
Thanks for sharing @gpfister! I'll close with the note to update to at least Xcode 14.3