Skip to content

Commit 66cbe38

Browse files
gaaclarkemboetger
authored andcommitted
fixes deeplinking in uiscenedelegate migrated projects (flutter#170452)
fixes flutter#170350 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent f250437 commit 66cbe38

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneDelegate.m

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,42 @@ - (void)windowScene:(UIWindowScene*)windowScene
4242
}
4343
}
4444

45+
static NSDictionary<UIApplicationOpenURLOptionsKey, id>* ConvertOptions(
46+
UISceneOpenURLOptions* options) {
47+
if (@available(iOS 14.5, *)) {
48+
return @{
49+
UIApplicationOpenURLOptionsSourceApplicationKey : options.sourceApplication
50+
? options.sourceApplication
51+
: [NSNull null],
52+
UIApplicationOpenURLOptionsAnnotationKey : options.annotation ? options.annotation
53+
: [NSNull null],
54+
UIApplicationOpenURLOptionsOpenInPlaceKey : @(options.openInPlace),
55+
UIApplicationOpenURLOptionsEventAttributionKey : options.eventAttribution
56+
? options.eventAttribution
57+
: [NSNull null],
58+
};
59+
} else {
60+
return @{
61+
UIApplicationOpenURLOptionsSourceApplicationKey : options.sourceApplication
62+
? options.sourceApplication
63+
: [NSNull null],
64+
UIApplicationOpenURLOptionsAnnotationKey : options.annotation ? options.annotation
65+
: [NSNull null],
66+
UIApplicationOpenURLOptionsOpenInPlaceKey : @(options.openInPlace),
67+
};
68+
}
69+
}
70+
71+
- (void)scene:(UIScene*)scene openURLContexts:(NSSet<UIOpenURLContext*>*)URLContexts {
72+
id appDelegate = FlutterSharedApplication.application.delegate;
73+
if ([appDelegate respondsToSelector:@selector(lifeCycleDelegate)]) {
74+
FlutterPluginAppLifeCycleDelegate* lifeCycleDelegate = [appDelegate lifeCycleDelegate];
75+
for (UIOpenURLContext* context in URLContexts) {
76+
[lifeCycleDelegate application:FlutterSharedApplication.application
77+
openURL:context.URL
78+
options:ConvertOptions(context.options)];
79+
};
80+
}
81+
}
82+
4583
@end

engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneDelegateTest.m

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,25 @@ - (void)testBridgeShortcut {
4242
performActionForShortcutItem:[OCMArg any]
4343
completionHandler:[OCMArg any]]);
4444
}
45+
46+
- (void)testOpenURL {
47+
id mockApplication = OCMClassMock([UIApplication class]);
48+
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
49+
id mockAppDelegate = OCMClassMock([FlutterAppDelegate class]);
50+
id mockLifecycleDelegate = OCMClassMock([FlutterPluginAppLifeCycleDelegate class]);
51+
OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
52+
OCMStub([mockAppDelegate lifeCycleDelegate]).andReturn(mockLifecycleDelegate);
53+
id windowScene = OCMClassMock([UIWindowScene class]);
54+
id urlContext = OCMClassMock([UIOpenURLContext class]);
55+
NSURL* url = [NSURL URLWithString:@"http://example.com"];
56+
OCMStub([urlContext URL]).andReturn(url);
57+
58+
FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
59+
[sceneDelegate scene:windowScene openURLContexts:[NSSet setWithArray:@[ urlContext ]]];
60+
61+
OCMVerify([(FlutterPluginAppLifeCycleDelegate*)mockLifecycleDelegate application:[OCMArg any]
62+
openURL:url
63+
options:[OCMArg any]]);
64+
}
65+
4566
@end

0 commit comments

Comments
 (0)