-
Notifications
You must be signed in to change notification settings - Fork 6k
Build iOS with -fapplication-extension flag #40972
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
| "-Werror=undeclared-selector", | ||
| ] | ||
| if (extension_safe) { | ||
| flutter_cflags_objc += [ "-fapplication-extension" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
macOS doesn't fail when building with this flag, but macOS does contain NSApplication code. I'm confused here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get this working either, might take more investigation to see how what flags Xcode is passing through when it shows the warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested the locally built mac engine.
Without with this flag, I got the warning when linking a share extension to the framework.
With this flag, there is no warning.
So it seemed like it is just working (which clearly is not since the mac os code does contain NSApplication.)
Will investigate more.
(I should have marked this PR as draft, it is not intended for reviewing yet before this macOS mystery is resolved)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into the headers, on iOS:
@property(class, nonatomic, readonly) UIApplication *sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
The shared application is marked as extension unavailable.
However, on macOS it is not.
@property (class, readonly, strong) __kindof NSApplication *sharedApplication;
In the document: https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW6 only linked to the UIApplication.sharedApplication, didn't mention NSApplication.
I create a sample mac framework having Require Only App-Extension-safe API turned on and having NSApplication.SharedApplication. It successfully compiled and a share extension can link to it without warning.
So I believe NSApplication.sharedApplication is compatible with extensions? So on mac, as long as the -fapplication-extension is in the build flags and there is no compile error, it will work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I believe NSApplication.sharedApplication is compatible with extensions? So on mac, as long as the
-fapplication-extensionis in the build flags and there is no compile error, it will work.
!!!
From my reading of the docs when they said sharedApplication without specifying an object I thought they meant either UIApplication or NSApplication.
Access a sharedApplication object, and so cannot use any of the methods on that object
If we don't need to do anything other than documentation for macOS that would be amazing!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also you could pull that very simple macOS flag-only work out of this so it would start working in the next stable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By "next stable" I just mean it can be available now-ish without needing to wait for all the iOS work to be correct.
common/config.gni
Outdated
| # Whether to build host-side development artifacts. | ||
| flutter_build_engine_artifacts = true | ||
|
|
||
| extension_safe = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe darwin_extension_safe and a comment? There are more "extension" concepts this could be confused with.
|
|
||
| if (extension_safe) { | ||
| ldflags = [ | ||
| "-F$framework_search_path", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surprised this wasn't needed before... maybe copy_and_verify_framework_module isn't actually working (ignoring the extension stuff)?
| #if !APPLICATION_EXTENSION_API_ONLY | ||
| // Checks if the top status bar should be visible. This platform ignores all | ||
| // other overlays | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't do this in my prototype PR, but ideally we could get rid of as many sharedApplication usages as possible.
-[UIApplication statusBarHidden] is actually deprecated in iOS 13:
@property(readonly, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden API_UNAVAILABLE(tvos) API_DEPRECATED("Use the statusBarManager property of the window scene instead.", ios(2.0, 13.0));Can you instead swap this to using the new API when 13 is @available, and fall back to sharedApplication statusBarHidden for older versions only? Probably best to do this in its own review though this can sit on in case it causes issues. I don't trust our testing coverage here.
From the [_engine.get() viewController] I think you could get .viewIfLoaded.window.windowScene?
I'm not sure if it's meaningful to have a status bar in an extension, though.
| #if !APPLICATION_EXTENSION_API_ONLY | ||
| // Note: -[UIApplication setStatusBarStyle] is deprecated in iOS9 | ||
| // in favor of delegating to the view controller | ||
| [[UIApplication sharedApplication] setStatusBarStyle:statusBarStyle]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setStatusBarStyle was deprecated in iOS 9 so we wouldn't even need a fallback or the macro (minimum is now iOS 11), if we can get a view controller here ([_engine.get() viewController]?)
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated API_DEPRECATED("Use -[UIViewController preferredStatusBarStyle]", ios(2.0, 9.0)) API_UNAVAILABLE(tvos);
Though I don't really understand the delegateToViewController logic or why we wouldn't want to pass it along to the embedder... #2732
| #if !APPLICATION_EXTENSION_API_ONLY | ||
| UIViewController* rootViewController = | ||
| [UIApplication sharedApplication].keyWindow.rootViewController; | ||
| if (engineViewController != rootViewController) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we still need to check something here in the share extension to avoid regressing #30939.
| UIWindowScene* windowScene = self.viewIfLoaded.window.windowScene; | ||
| [self performOrientationUpdateOnWindowScene:windowScene]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could just use this logic instead of anything in the #else, I didn't test it though so in my PR I only used it in the APPLICATION_EXTENSION_API_ONLY check.
| } else { | ||
| #if !APPLICATION_EXTENSION_API_ONLY | ||
| UIInterfaceOrientationMask currentInterfaceOrientation = | ||
| 1 << [[UIApplication sharedApplication] statusBarOrientation]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If available you could check the self.viewIfLoaded.window.windowScene.statusBarOrientation since this was deprecated in iOS 13.
@property(readonly, nonatomic) UIInterfaceOrientation statusBarOrientation API_UNAVAILABLE(tvos) API_DEPRECATED("Use the interfaceOrientation property of the window scene instead.", ios(2.0, 13.0));
| UIContentSizeCategory category = | ||
| self.mainScreenIfViewLoaded.traitCollection.preferredContentSizeCategory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just use this in all cases since this is all available on iOS 10+, but I didn't test it so I put it in the macro for safety in my PR.
| "-Werror=undeclared-selector", | ||
| ] | ||
| if (extension_safe) { | ||
| flutter_cflags_objc += [ "-fapplication-extension" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get this working either, might take more investigation to see how what flags Xcode is passing through when it shows the warning.
|
This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again. |
shell/platform/darwin/ios/BUILD.gn
Outdated
| output_name = "Flutter" | ||
|
|
||
| ldflags = [ "-Wl,-install_name,@rpath/Flutter.framework/Flutter" ] | ||
| ldflags = [ "-Wl,-install_name,&_flutter_framework_dir/Flutter" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ldflags = [ "-Wl,-install_name,&_flutter_framework_dir/Flutter" ] | |
| ldflags = [ "-Wl,-install_name,$_flutter_framework_dir/Flutter" ] |
f1154c2 to
5761631
Compare
Build iOS and macOS Obj-C with -fapplication-extension flag Linker flag Find the App.framework asset URL from the app extension Remove load draft extension safe built flag format gn format macos test fix clang tidy rename flag add linker flag format draft format: add LINE EOF fix typo format fix run search path fix copying fix build.gn format format
original PR: #40332
For testing,
copy_and_verify_framework_moduleproduces a warning message if the engine is not built with extension_safe when asked to. This warning message does not fail build on its own. A new CI step needs to be added to capture the warning message and fail.fixes flutter/flutter#124286, flutter/flutter#124290, flutter/flutter#124289
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.