fix(ios): adopt FlutterSceneLifeCycleDelegate for UIScene deep link support#438
Conversation
…upport The plugin only implemented AppDelegate-based lifecycle methods for deep linking. Since Flutter 3.41 auto-migrates apps to UIScene by default, UIKit no longer calls application:openURL:options: or application:continueUserActivity: — routing everything through the scene delegate instead. This caused deep links to be silently dropped on iOS apps using Flutter 3.41+. Fix: - Adopt FlutterSceneLifeCycleDelegate in AppsflyerSdkPlugin - Register via [registrar addSceneDelegate:instance] (iOS 13+) - Add scene:openURLContexts: for warm-start URI-scheme deep links - Add scene:willConnectToSession:options: for cold-start URI-scheme deep links - Add scene:continueUserActivity: for Universal Links via UIScene Verified on iOS 18.4 simulator with Flutter 3.41.4. Both cold-start and warm-start deep link callbacks now reach the plugin correctly without requiring any app-side workaround. Fixes: DELIVERY-114618 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Deprecated getViewController not fixed - ios/Classes/AppsflyerSdkPlugin.m While not directly related to deep linking, this is a ticking time bomb for any code path that calls it under |
|
Per the Flutter migration guide for plugins, the minimum Flutter SDK should be bumped to >=3.38.0 (or the protocol adoption must be compile-time guarded). Currently i see it's |
- getViewController: replaced deprecated UIApplication.delegate.window (returns nil under UIScene) with UIWindowScene lookup on iOS 13+, falling back to the AppDelegate window for older iOS versions. - pubspec.yaml: bumped Flutter minimum SDK from >=1.10.0 to >=3.38.0 as required by the Flutter plugin migration guide for adopting FlutterSceneLifeCycleDelegate. Addresses review comments on PR #438. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The example app declares .env as a Flutter asset (needed for flutter_dotenv), but .env is gitignored and not present in CI. This caused both Android and iOS builds to fail with "No file or variants found for asset: .env". Add a CI step to create a minimal dummy .env before each platform build. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of hard-requiring Flutter >=3.38.0, wrap FlutterSceneLifeCycleDelegate protocol adoption and addSceneDelegate with #if __has_include guards. - Flutter >=3.38 (header present): UIScene delegate registered, all three scene callbacks active — deep links work under UIScene migration. - Flutter <3.38 (header absent): guard skips it at compile time, plugin falls back to application:openURL: — backward compatible. pubspec.yaml reverts flutter constraint to >=1.10.0 (no breaking change). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two fixes based on review feedback:
1. openURLContexts / willConnectToSession: pass sourceApplication from
UIOpenURLContext.options instead of empty @{}, so AppsFlyer SDK receives
correct attribution metadata on URI-scheme deep links.
2. willConnectToSession: also iterate connectionOptions.userActivities and
forward NSUserActivityTypeBrowsingWeb entries to continueUserActivity:,
fixing cold-start Universal Links under UIScene (the core reported issue).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Fixed in commit 2317776. |
|
Addressed in commit 783530c with a compile-time |
|
Replying to #438 (comment) —
Fixed. + (FlutterViewController*) getViewController {
UIWindow *window = nil;
if (@available(iOS 13.0, *)) {
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive) {
window = scene.windows.firstObject;
break;
}
}
}
if (window == nil) {
window = [[[UIApplication sharedApplication] delegate] window];
}
UIViewController *topMostViewControllerObj = window.rootViewController;
return (FlutterViewController *)topMostViewControllerObj;
} |
Dani-Koza-AF
left a comment
There was a problem hiding this comment.
Great work @Kobikg78 !
Summary
Fixes deep link breakage on iOS apps using Flutter 3.41+ (DELIVERY-114618).
Problem
Flutter 3.41 auto-migrates apps to UIScene by default. When UIScene is active, UIKit routes deep links through the scene delegate (
scene:openURLContexts:,scene:willConnectToSession:options:) rather than the traditional AppDelegate methods (application:openURL:options:). The plugin only implemented the AppDelegate path, causing deep links to be silently dropped.Fix
AppsflyerSdkPluginnow conforms toFlutterSceneLifeCycleDelegateand registers via[registrar addSceneDelegate:instance](iOS 13+). Three new methods added:scene:willConnectToSession:options:— cold-start URI-scheme deep linksscene:openURLContexts:— warm-start URI-scheme deep linksscene:continueUserActivity:— Universal Links via UISceneNo app-side changes required.
Testing
scene:willConnectToSession:options:fires beforestartSDK,onDeepLinking Status.FOUNDdelivered correctlyFixes: DELIVERY-114618