Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter app references private classes on iOS #124008

Closed
aj-dt opened this issue Apr 3, 2023 · 7 comments · Fixed by flutter/engine#41873
Closed

Flutter app references private classes on iOS #124008

aj-dt opened this issue Apr 3, 2023 · 7 comments · Fixed by flutter/engine#41873
Assignees
Labels
engine flutter/engine repository. See also e: labels. found in release: 3.7 Found to occur in 3.7 found in release: 3.9 Found to occur in 3.9 P1 High-priority issues at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version

Comments

@aj-dt
Copy link

aj-dt commented Apr 3, 2023

Flutter apps reference private classes __UIVisualEffectBackdropView and __UIVisualEffectSubview on iOS.

Although this has so far not resulted in app rejections, it is a risk factor for anyone relying on the Flutter platform given Apple's notoriously opaque app submission process.

Steps to Reproduce

This is visible directly in the code, e.g. FlutterPlatformViews_Internal.mm:

UIView* view = visualEffectView.subviews[i];
if ([view isKindOfClass:NSClassFromString(@"_UIVisualEffectBackdropView")]) {
  ...
}

Or, if one unpacks a flutter-built ipa:

flutter create private_repro1
cd private_repro1
flutter build ipa --release
cd build/ios/ipa
unzip private_repro1.ipa
cd private_repro1
strings Frameworks/Flutter.framework/Flutter| grep UIVisualEffect

Expected results:

There would be no reference to private iOS classes

Actual results:

As of flutter 3.7.8 there are references to two private classes:

strings Frameworks/Flutter.framework/Flutter| grep UIVisualEffect
_UIVisualEffectBackdropView
_UIVisualEffectSubview
Code sample
Logs
@exaby73 exaby73 added the in triage Presently being triaged by the triage team label Apr 3, 2023
@exaby73
Copy link
Member

exaby73 commented Apr 3, 2023

Hello @aj-dt. Could you link to Apple docs specifying that private classes should not be used?

@exaby73 exaby73 added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Apr 3, 2023
@aj-dt
Copy link
Author

aj-dt commented Apr 4, 2023

Hi @exaby73,
Apple's Developer License Agreement[1], section 3.3.1:

Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs

Although it does not reference classes directly, Apple are not exactly known for their laissez faire interpretation of their own rules. While this usage has apparently been tolerated, it represents a risk that could start causing rejections at any time.

[1] https://developer.apple.com/support/downloads/terms/apple-developer-program/Apple-Developer-Program-License-Agreement-20220606-English.pdf

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Apr 4, 2023
@exaby73
Copy link
Member

exaby73 commented Apr 4, 2023

This seems very vague to me. It doesn't really specify what the meaning of a "private API" is. I'll leave this for interpretation and label this issue

@exaby73 exaby73 added platform-ios iOS applications specifically engine flutter/engine repository. See also e: labels. found in release: 3.7 Found to occur in 3.7 found in release: 3.9 Found to occur in 3.9 and removed in triage Presently being triaged by the triage team labels Apr 4, 2023
@leighajarett
Copy link
Contributor

leighajarett commented Apr 4, 2023

Thanks for flagging this! These APIs were used to add blurs on Platform Views (#43902).

In the design doc, we called out some risks and a future plan to migrate to use SwiftUI. For now, we will keep this as a lower priority, but we will continue to investigate the migration for the future.

@leighajarett leighajarett added the P3 Issues that are less important to the Flutter project label Apr 4, 2023
@hellohuanlin
Copy link
Contributor

I wouldn't worry about it - it's not invoking any private methods

@EthanArbuckle
Copy link

Hello!

I wouldn't worry about it - it's not invoking any private methods

Any references to such APIs (which includes selectors, classes, or symbols) all fall into the category of "using a non-public API".

Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs

This seems very vague to me. It doesn't really specify what the meaning of a "private API" is

I agree Apple could have been more clear here; they have a known history of not documenting their "blockers" very well (likely on purpose to avoid people finding workarounds). However, their language is more verbose when you actually receive one of the blockers. I'll include some real examples below, but i'd first like to note why I believe this symbol to be non-public:

  1. The class is prefixed with _, a well-known indicator of something being non-public. Examples of this are Class Clusters, such as __NSDictionaryIor __NSCFString (you've likely seen these show up in crashes/stacktraces before, but you'll find no public documentation from Apple on them because they are non-public and should not be used directly).

  2. No header exists for the _UIVisualEffectSubview class. If an API is excluded from the public SDK, and can only be accessed by doing dynamic class lookups (NSClassFromString()), Apple did not intend for you to access it.

  3. The UIKit binary that implements this class is located in a directory named PrivateFrameworks:

Screen Shot 2023-05-03 at 11 30 53

Now, for some examples of real-world rejection Apple has issued regarding Non-Public API Usage. Apple's internal ID for Non-Public API Usage blockers is ITMS-90338 -- searching around for this will yield many examples of rejections developers have received. The language varies slightly between some of them so I'll highlight a couple different ones i've encountered.

  1. ITMS-90338: Non-public API usage - The app references non-public selectors:

The app references non-public selectors. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed.

Real examples of developers being blocked:

  1. ITMS-90338: Non-public API usage - The app references non-public symbols:

The app references non-public symbols in APP NAME: _SSL_CTX_set_options, _SSL_session_reused. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions.

Real examples of developers being blocked:

You'll see that the last example was on this repo. Flutter was referencing a private symbol, and the Flutter team had to remove it to stay compliant with Apple's rules.

Given the precedence of apps being blocked for simply referencing non-public APIs, and the history of the Flutter team recognizing that private APIs should not be used, I'd hope for this issue to be considered higher priority than what I feel it is currently assessed at.

Please let me know if you have any questions or if you'd like me to further clarify any of the points I made.

I appreciate you taking the time to consider this.

Thanks!
EA

@hellohuanlin hellohuanlin self-assigned this May 9, 2023
@hellohuanlin hellohuanlin added P1 High-priority issues at the top of the work list and removed P3 Issues that are less important to the Flutter project labels May 9, 2023
auto-submit bot pushed a commit to flutter/engine that referenced this issue May 10, 2023
The original code creates an internal `class` which is alarming: 

`NSClassFromString(@"_UIVisualEffectBackdropView")`

This PR removes such usage. 

*List which issues are fixed by this PR. You must list at least one issue.*

Fixes flutter/flutter#124008

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
@exaby73 exaby73 added the r: fixed Issue is closed as already fixed in a newer version label May 13, 2023
@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
engine flutter/engine repository. See also e: labels. found in release: 3.7 Found to occur in 3.7 found in release: 3.9 Found to occur in 3.9 P1 High-priority issues at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants