Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
|
@jeffwall-curlewlabs Thanks for the PR. Please sign the CLA and we'll take a look |
firebase#16449 introduced an AuthNotificationApplication protocol so AuthNotificationManager could be unit tested with a fake. Because UIApplicationDelegate.application(_:didReceiveRemoteNotification: fetchCompletionHandler:) takes a concrete UIApplication, the call site gained a downcast with a `?? UIApplication.shared` fallback. UIApplication.shared is NS_EXTENSION_UNAVAILABLE_IOS, so since 12.18.0 FirebaseAuth no longer compiles for targets built with -application-extension. Vend the UIApplication the delegate callback needs through the protocol instead. The production conformance is UIApplication itself and returns self; the test fakes return UIApplication.shared from the test target, which is not built for app extensions. That removes UIApplication.shared from the module entirely rather than hiding it behind a runtime lookup. Behaviour is unchanged: in production self.application is always a real UIApplication, because AuthNotificationManager is only constructed in Auth.protectedDataInitialization() after its isAppExtension() early return, and the fake delegates in the tests ignore the argument. Fixes firebase#16583.
c8936dc to
dffec26
Compare
|
Tried this on a real project — it fixes the reported error, but the app-extension build still fails further along. Wanted to flag this before it lands, in case the goal is "app-extension builds work again" rather than specifically "this one line compiles." Setup: CocoaPods 1.16.2, Xcode 26.6, What I did: applied this PR's three edits to the vendored pod source (protocol member, Result: SWIFT_CLASS("_TtC12FirebaseAuth16AuthURLPresenter")
@interface AuthURLPresenter : NSObject <SFSafariViewControllerDelegate>
SWIFT_CLASS("_TtC12FirebaseAuth21AuthWebViewController")
@interface AuthWebViewController : UIViewController <WKNavigationDelegate>Diffing the generated header between the two configurations is more informative than the errors themselves: So under Reproduces byte-identically from a wiped DerivedData, so it isn't incremental-build state; I checked that first and was wrong about it. I'm not sure whether this is a FirebaseAuth issue or a CocoaPods static-framework interaction on my side, so take it as a data point rather than a bug report. But the practical outcome is that with this patch applied, clearing Happy to test a follow-up patch if useful. |
|
Thanks for checking. We'll need to do some more digging. Here's Gemini's summary: This is a fascinating edge case, and you've hit on a very obscure intersection between Swift's Here is the exact mechanism of why the extension-only build exposes more to Objective-C than the regular one, and why it fails. The Mechanism1. The Swift Compiler "Executable" Quirk 2. The 3. The How the PR can fix thisSince the root issue is Option A: Enforce Library Evolution (Build Settings) Option B: Use Option C: Swift You are entirely correct that |
|
Closing in favor of #16594. I've cherry-picked your commit into that one, @jeffwall-curlewlabs. This way, I could make some small revisions and get it merged for code freeze. |
|
Pivoting back to this PR. The added test revisions caused more problems than they were worth. |
|
Thanks! |
|
Thanks for testing, @itamarbareket. I haven't been able to reproduce that particular issue. I created #16595, but am unsure if that'll makes a difference for you. |
Happy to help! Thank you for creating the other test cases also. Great to get coverage for these cases. |
Fixes #16583.
The problem
#16449 added an
AuthNotificationApplicationprotocol soAuthNotificationManagercould be unit tested with a fake.UIApplicationDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:)takes a concreteUIApplication, so the call site gained a downcast with a fallback:UIApplication.sharedisNS_EXTENSION_UNAVAILABLE_IOS, so since 12.18.0 FirebaseAuth does not compile for targets built with-application-extension:The fix
Vend the
UIApplicationthe delegate callback needs through the protocol. The production conformance isUIApplicationitself, so it returnsself; the two test fakes returnUIApplication.sharedfrom the test target, which is not built for app extensions. That takesUIApplication.sharedout of the SDK module entirely rather than hiding it behind a runtime lookup.Behaviour is unchanged. In production
self.applicationis always a realUIApplication—AuthNotificationManageris constructed only inAuth.protectedDataInitialization(), after itsGULAppEnvironmentUtil.isAppExtension()early return — and the fake delegates in the tests ignore the argument.Alternative considered
The narrower change would be the reflection idiom already used at
Auth.swift:1704,AuthDefaultUIDelegate.swift:34andTOTPSecret.swift:64, which would keep the diff inside one file. I went with the protocol because those three sites genuinely need the shared application at runtime in an app, whereas this one never does. Happy to switch if you would prefer the smaller change.Verification
main(168647e)error: 'shared' is unavailable in application extensions for iOS** BUILD SUCCEEDED **12.17.0tag (control)** BUILD SUCCEEDED **AuthUnitpasses on iOS Simulator, Xcode 26.6. SwiftFormat 0.55.5, theMintfilepin, reports no formatting changes needed.Notes, not part of this change
APPLICATION_EXTENSION_API_ONLY = YES, which is how this reached a release. Under CocoaPods a consumer's extension target surfaced it as a build error, but SwiftPM builds each package product once without-application-extension([SR-14944] SwiftPM and app extensions (compiles every package with the -application-extension flag) swiftlang/swift-package-manager#4402), so SwiftPM consumers link the unsafe call into their.appexwith no diagnostic. With 12.19.0 the last CocoaPods release, that error path goes away. Glad to open a separate PR adding an extension-safe build to CI if that would be useful./// A class represents a credential that proves the identity of the app.doc comment and the@preconcurrencyattribute attached to the new protocol rather than toAuthNotificationManager. Both look accidental and@preconcurrencyis behaviour-affecting, so I left them for you rather than fold an unrelated change in here.