flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
162.18k stars 26.64k forks source link

Determine how to handle privacy manifests in packages #131940

Open stuartmorgan opened 9 months ago

stuartmorgan commented 9 months ago

[Edit April 22, 2024]:


See https://github.com/flutter/flutter/issues/131495 for more background. This splits out the specific question of how packages should handle privacy manifests and required reason API metadata, and what the flutter needs to do to support that.

Background docs:

Capturing from my comment in the original issue:

It seems like we'll either need to:

  • leave this up to app developers to deal with (e.g., via finding the transitive usage and asking developers to list the reasons in their READMEs), which isn't going to be a good experience, or
  • build a system for arbitrary pub packages to declare privacy manifests, and for the tool to bundle them all together.

We'll also need to investigate how exactly Apple is defining what an SDK is from the standpoint of the automated checks. E.g., if someone's project is configured to build plugins as frameworks, rather than static libraries, will putting the manifests into those frameworks rather than the app be mandatory?

flutter-triage-bot[bot] commented 9 months ago

Issue is assigned to multiple teams (ecosystem, ios). Please ensure the issue has only one team-* label at a time. Use fyi-* labels to have another team look at the issue without reassigning it.

stuartmorgan commented 7 months ago

E.g., if someone's project is configured to build plugins as frameworks, rather than static libraries, will putting the manifests into those frameworks rather than the app be mandatory?

There's still no clarity from Apple on this. It almost certainly wouldn't be required for non-framework builds since there's no obvious automated way for the release process to know what code came from a static library, but it's also unclear if it's possible to aggregate from static libraries in a well-defined way.

As for the mechanism for doing this under the current plugin system, these's some Cocoapods discussion starting at https://github.com/CocoaPods/CocoaPods/issues/10325#issuecomment-1650606427

ryanheise commented 7 months ago

FYI I received this from Apple this morning:

Hello:

This message is intended for Ryan Heise

I lead the Creative Pro Partnership Management team in Apple Worldwide Developer Relations. We manage the relationship with developers who create developer tools, photography, music, 2D/3D design, 3D and gaming pipeline, and production-focused apps and hardware.

As you may know, in June, Apple announced new features to help users understand developers’ privacy and data collection and sharing practices. These new features include privacy manifests and signatures, which we encourage all third-party SDKs to adopt to provide transparency to users and help secure the software supply chain. Third-party SDKs that impact user privacy will be expected to include a privacy manifest and signature, and starting in Spring 2024, new and updated apps that include these third-party SDKs will need to include their manifest and signature to submit to the App Store.

The SDKs you are associated with, audio_session and just_audio, may have significant impact on the privacy of the users of apps that include it. We’re reaching out to make sure you are aware of this upcoming change, and to provide resources to help. If you have any questions about implementing privacy manifests and/or signatures, you can reach out to me and I’ll do my best to escalate your questions.

Here are some additional resources that may be helpful:

In my case, the audio_session package has a flag to compile in/out the API that accesses the microphone, which is an API that impacts privacy. In Apple's eyes, it seems each plugin is an SDK that provides its own privacy manifest file. But in the presence of conditional compiling, it is unclear whether the privacy manifest is something that should be static, or something that I will need to generate differently depending on the compile flags.

Another plugin that does this sort of conditional compiling is permission_handler.

I will follow up with Apple to see if they can clarify.

stuartmorgan commented 5 months ago

https://developer.apple.com/support/third-party-SDK-requirements/ now has a list that includes a number of Flutter plugins. I'll file issues about our own plugins that are on that list, and also file issue with the third-party plugins. We're still trying to understand how this impacts both our own plugins (e.g., I'm not sure what video_player would list at all), and in general how SDKs that are just allowing apps to access these things rather than using them directly (e.g., someone could use webview_flutter to gather browsing history, but webview_flutter does not itself collect anything) are supposed to list things in a privacy manifest.

zoeyfan commented 5 months ago

@stuartmorgan do you know if this change applies to the Flutter GMA plugin: https://github.com/googleads/googleads-mobile-flutter/tree/main/packages/google_mobile_ads @LTPhantom as FYI

stuartmorgan commented 5 months ago

@zoeyfan I don't have any more information than what's on the website currently. The general docs say they "encourage" everyone to adopt the manifest, but only seem (from my reading of the docs, which could be incorrect) to be requiring it for specific SDKs currently. How those SDKs were chosen is currently opaque.

stuartmorgan commented 5 months ago

Capturing from initial discussions in the various issues I filed with affected plugins: there seems to be general confusion about what the term "collect" is intended to mean in relation to many of the plugins on the list (which are like my example of webview_flutter above, which I would not consider to be collecting any data), and therefore what these plugins are expected to put in a privacy manifest. So far it seems that nobody who has requested clarification from Apple on this has received an answer yet.

I would welcome any comments here from plugin developers who do receive clarification on this in the future so that we can share knowledge in the ecosystem about how to proceed.

stuartmorgan commented 4 months ago

FWIW, the guidance we have received with regard to our own plugins that are on the required SDK list but do not collect any private data or use any required-reason APIs is that the framework should include a privacy manifest that does not list any data or required-reason APIs (i.e., is empty except for the privacy manifest structure).

stuartmorgan commented 3 months ago

Questions about specific plugins are off-topic here.

stuartmorgan commented 1 month ago

Based on https://github.com/flutter/flutter/issues/145269 it looks like there's currently a lot of confusion around apps being built without use_frameworks (or with dependencies that force static linking), since anything plugins use then shows up as usage in Runner.

Edit: Updated April 22, 2024] Please see this comment for information if you are an app developer receiving an ITMS-91053 warning.

WARNING: There have been comments in various issue that provide a large block of text and suggest just copying it wholesale into your app's privacy manifest file. I would strongly recommend not doing this. The contents of a privacy manifest file are an attestation to Apple that you are using data and/or APIs only in the ways described in that file. A random comment on the internet is very unlikely to correspond to exactly what your project is doing, so copying arbitrary content could easily result in you misrepresenting your app's behavior to Apple.

(I will be hiding any comments in the Flutter issue tracker that include, or link directly to, instructions that suggest copying specific arbitrary text, as it's potentially harmful.)

rajeshbdabhi commented 1 month ago

i am facing same issue. i have also followed https://github.com/FlutterFlow/flutterflow-issues/issues/2527#issuecomment-1998885560. but this is also not helpful for me still getting app rejection with Missing API declaration

philIip commented 1 month ago

Based on #145269 it looks like there's currently a lot of confusion around apps being built without use_frameworks, since anything plugins use then shows up as usage in Runner.

It's not clear if people just aren't yet using versions of the plugins that have manifests, or if Apple isn't aggregating in the Cocoapods static build resource bundle manifests the way we had hoped. If it's the latter, @jmagman we will need docs around how to manually consolidate the contents of these files, and maybe even custom tooling to alert developers at build time :(

I'll see if we can get clarification from Apple about expected behavior here.

In the meantime, for developers getting ITMS-91053 warnings, some steps that may help resolve it:

  • Run flutter pub upgrade to ensure that you have the latest version of all plugins, direct and transitive. This is necessary since many plugins have only recently added their manifests.
  • If you still have the issue, there are two different options:

    • Try adding this line to your ios/Podfile. This will cause plugins to be packaged as frameworks.

    • If you still get warnings on upload, that should change the warning to identify the plugin(s) that use the API, instead of indicating that it's coming from Runner.

    • In that case, you would need to file issues against the developers of those plugins.

    • If you don't use use_frameworks:

    • Create a privacy manifest for your application

    • Run find build/ios/iphoneos -name *.xcprivacy in your project. For anything of the form <some_plugin_name>.bundle/PrivacyInfo.xcprivacy, look at the declarations they make, and copy all of the array entries into the file you created above.

WARNING: There have been comments in various issue that provide a large block of text and suggest just copying it wholesale into your app's privacy manifest file. I would strongly recommend not doing this. The contents of a privacy manifest file are an attestation to Apple that you are using data and/or APIs only in the ways described in that file. A random comment on the internet is very unlikely to correspond to exactly what your project is doing, so copying arbitrary content could easily result in you misrepresenting your app's behavior to Apple.

(I will be hiding any comments in the Flutter issue tracker that include, or link directly to, instructions that suggest copying specific arbitrary text, as it's potentially harmful.)

hi @stuartmorgan, i'm driving this effort for react native and i just want to give you a data point from our side. my understanding as of now is that anything that is not being pulled in as a 3rd party distributed xcframework is essentially will be pulled into app source will need the privacy manifest content to live in the app's privacy manifest. so essentially the burden is on userland.

rajeshbdabhi commented 1 month ago

this solution is worked for me

aamirki commented 1 month ago

If you still get warnings on upload, that should change the warning to identify the plugin(s) that use the API, instead of indicating that it's coming from Runner.

Thanks for the guide @stuartmorgan, I already had use_frameworks! set in the Podfile but the email warnings are still attributing the errors to Runner. Example: ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons

Are you aware of any other steps needed to be done to determine which plugins are producing the error? And is there a way to get this list without re-submitting builds to Apple each time?

jmagman commented 1 month ago

Flutter itself has a compliant privacy manifest (as far as we are aware). If you're seeing ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file it could mean:

  1. You are using a static plugin (podspec contains s.static_framework = true) that has declared a privacy manifest, but you're on an older version of that package and you should update.
  2. You are using a static plugin that has not declared a privacy manifest. We'd really like to know exactly which plugin that is, and reach out (or you as their customer reach out) and get them to add one.
  3. Much more concerning, the static plugin is declaring a privacy manifest, but there's something we're missing about how Apple is enforcing this requirement.

[Edited April 22, 2024] If you're seeing this, before you add any workarounds you read online, please see this comment.

Thank you so much!

naivetoby commented 1 month ago

For Chinese Developers

fluwx: ^4.5.0 tobias: ^3.3.1 jpush_flutter: ^2.5.1 => https://github.com/jpush/jpush-flutter-plugin

rettet-die-stille commented 1 month ago

Please attach:

  1. pubspec.yaml and pubspec.lock
  2. ios/Podfile
  3. Confirm whether or not you have added any native code directly to your Runner? (E.g., modified the Swift or Objective-C code in the ios/ directory yourself.)
  4. If you're willing, your actual built .ipa or .xcarchive file so we can look at the file structure of your plugins.

Thank you so much!

I am happy to send the files... , but how? As a comment?

jmagman commented 1 month ago

Yes, drag in the requested files into a comment to this GitHub issue to attach them.

christocracy commented 1 month ago

I'm a plugin author of background_fetch. This plugin includes a Privacy Manifest within its own TSBackgroundFetch.xcframework

we'd really like help tracking this down for everyone so no one (except plugin authors in case 2 above) need to do anything manually.

pubspec.yaml ```yaml name: background_fetch_example description: Demonstrates how to use the background_fetch plugin. version: 1.1.0+2 environment: sdk: ">=3.3.0 <4.0.0" dependencies: flutter: sdk: flutter shared_preferences: ^2.2.0 http: ^1.1.0 cupertino_icons: ^1.0.5 dev_dependencies: test: ^1.5.1 flutter_driver: sdk: flutter background_fetch: ^1.3.1 ## # Temporarily disabled import from path # path: ../ # flutter: uses-material-design: true ```
pubspec.lock ```yaml # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: _fe_analyzer_shared: dependency: transitive description: name: _fe_analyzer_shared sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted version: "64.0.0" analyzer: dependency: transitive description: name: analyzer sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted version: "6.2.0" args: dependency: transitive description: name: args sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" url: "https://pub.dev" source: hosted version: "2.3.2" async: dependency: transitive description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted version: "2.11.0" background_fetch: dependency: "direct dev" description: name: background_fetch sha256: "67d28aa747d344e8ab4cb56f0fba4f957c1d41504fc6be1ef275864000b30eb6" url: "https://pub.dev" source: hosted version: "1.3.1" boolean_selector: dependency: transitive description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted version: "2.1.1" characters: dependency: transitive description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted version: "1.3.0" clock: dependency: transitive description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted version: "1.18.0" convert: dependency: transitive description: name: convert sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" url: "https://pub.dev" source: hosted version: "3.1.1" coverage: dependency: transitive description: name: coverage sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" url: "https://pub.dev" source: hosted version: "1.7.2" crypto: dependency: transitive description: name: crypto sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 url: "https://pub.dev" source: hosted version: "3.0.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be url: "https://pub.dev" source: hosted version: "1.0.5" fake_async: dependency: transitive description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 url: "https://pub.dev" source: hosted version: "2.0.1" file: dependency: transitive description: name: file sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted version: "7.0.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" flutter_driver: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" flutter_test: dependency: transitive description: flutter source: sdk version: "0.0.0" flutter_web_plugins: dependency: transitive description: flutter source: sdk version: "0.0.0" frontend_server_client: dependency: transitive description: name: frontend_server_client sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" url: "https://pub.dev" source: hosted version: "3.2.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter source: sdk version: "0.0.0" glob: dependency: transitive description: name: glob sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted version: "2.1.2" http: dependency: "direct main" description: name: http sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted version: "1.1.0" http_multi_server: dependency: transitive description: name: http_multi_server sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" url: "https://pub.dev" source: hosted version: "3.2.1" http_parser: dependency: transitive description: name: http_parser sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" url: "https://pub.dev" source: hosted version: "4.0.2" io: dependency: transitive description: name: io sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" url: "https://pub.dev" source: hosted version: "1.0.4" js: dependency: transitive description: name: js sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted version: "0.6.7" leak_tracker: dependency: transitive description: name: leak_tracker sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" url: "https://pub.dev" source: hosted version: "10.0.0" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 url: "https://pub.dev" source: hosted version: "2.0.1" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 url: "https://pub.dev" source: hosted version: "2.0.1" logging: dependency: transitive description: name: logging sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" url: "https://pub.dev" source: hosted version: "1.1.1" matcher: dependency: transitive description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted version: "0.8.0" meta: dependency: transitive description: name: meta sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted version: "1.11.0" mime: dependency: transitive description: name: mime sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e url: "https://pub.dev" source: hosted version: "1.0.4" node_preamble: dependency: transitive description: name: node_preamble sha256: "8ebdbaa3b96d5285d068f80772390d27c21e1fa10fb2df6627b1b9415043608d" url: "https://pub.dev" source: hosted version: "2.0.1" package_config: dependency: transitive description: name: package_config sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" url: "https://pub.dev" source: hosted version: "2.1.0" path: dependency: transitive description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted version: "1.9.0" path_provider_linux: dependency: transitive description: name: path_provider_linux sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 url: "https://pub.dev" source: hosted version: "2.1.11" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 url: "https://pub.dev" source: hosted version: "2.0.5" path_provider_windows: dependency: transitive description: name: path_provider_windows sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c url: "https://pub.dev" source: hosted version: "2.1.3" platform: dependency: transitive description: name: platform sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a url: "https://pub.dev" source: hosted version: "2.1.3" pool: dependency: transitive description: name: pool sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" url: "https://pub.dev" source: hosted version: "1.5.1" process: dependency: transitive description: name: process sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted version: "5.0.2" pub_semver: dependency: transitive description: name: pub_semver sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" url: "https://pub.dev" source: hosted version: "2.1.3" shared_preferences: dependency: "direct main" description: name: shared_preferences sha256: "0344316c947ffeb3a529eac929e1978fcd37c26be4e8468628bac399365a3ca1" url: "https://pub.dev" source: hosted version: "2.2.0" shared_preferences_android: dependency: transitive description: name: shared_preferences_android sha256: fe8401ec5b6dcd739a0fe9588802069e608c3fdbfd3c3c93e546cf2f90438076 url: "https://pub.dev" source: hosted version: "2.2.0" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation sha256: f39696b83e844923b642ce9dd4bd31736c17e697f6731a5adf445b1274cf3cd4 url: "https://pub.dev" source: hosted version: "2.3.2" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1" url: "https://pub.dev" source: hosted version: "2.3.0" shared_preferences_web: dependency: transitive description: name: shared_preferences_web sha256: "7347b194fb0bbeb4058e6a4e87ee70350b6b2b90f8ac5f8bd5b3a01548f6d33a" url: "https://pub.dev" source: hosted version: "2.2.0" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted version: "2.3.2" shelf: dependency: transitive description: name: shelf sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c url: "https://pub.dev" source: hosted version: "1.4.0" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler sha256: aef74dc9195746a384843102142ab65b6a4735bb3beea791e63527b88cc83306 url: "https://pub.dev" source: hosted version: "3.0.1" shelf_static: dependency: transitive description: name: shelf_static sha256: e792b76b96a36d4a41b819da593aff4bdd413576b3ba6150df5d8d9996d2e74c url: "https://pub.dev" source: hosted version: "1.1.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 url: "https://pub.dev" source: hosted version: "1.0.3" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" url: "https://pub.dev" source: hosted version: "2.1.1" source_maps: dependency: transitive description: name: source_maps sha256: "490098075234dcedb83c5d949b4c93dad5e6b7702748de000be2b57b8e6b2427" url: "https://pub.dev" source: hosted version: "0.10.11" source_span: dependency: transitive description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted version: "1.2.0" sync_http: dependency: transitive description: name: sync_http sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" url: "https://pub.dev" source: hosted version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted version: "1.2.1" test: dependency: "direct dev" description: name: test sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f url: "https://pub.dev" source: hosted version: "1.24.9" test_api: dependency: transitive description: name: test_api sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted version: "0.6.1" test_core: dependency: transitive description: name: test_core sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a url: "https://pub.dev" source: hosted version: "0.5.9" typed_data: dependency: transitive description: name: typed_data sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" url: "https://pub.dev" source: hosted version: "1.3.1" vector_math: dependency: transitive description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted version: "2.1.4" vm_service: dependency: transitive description: name: vm_service sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted version: "13.0.0" watcher: dependency: transitive description: name: watcher sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" url: "https://pub.dev" source: hosted version: "1.0.2" web_socket_channel: dependency: transitive description: name: web_socket_channel sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b url: "https://pub.dev" source: hosted version: "2.3.0" webdriver: dependency: transitive description: name: webdriver sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted version: "3.0.3" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" url: "https://pub.dev" source: hosted version: "1.2.0" win32: dependency: transitive description: name: win32 sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 url: "https://pub.dev" source: hosted version: "3.1.3" xdg_directories: dependency: transitive description: name: xdg_directories sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted version: "1.0.4" yaml: dependency: transitive description: name: yaml sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" url: "https://pub.dev" source: hosted version: "3.1.1" sdks: dart: ">=3.3.0 <4.0.0" flutter: ">=3.13.0" ```
ios/Podfile ```ruby # Uncomment this line to define a global platform for your project platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } def flutter_root generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) unless File.exist?(generated_xcode_build_settings_path) raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end File.foreach(generated_xcode_build_settings_path) do |line| matches = line.match(/FLUTTER_ROOT\=(.*)/) return matches[1].strip if matches end raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) flutter_ios_podfile_setup target 'Runner' do flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) end end ```

Confirm whether or not you have added any native code directly to your Runner? (E.g., modified the Swift or Objective-C code in the ios/ directory yourself.)

No.

If you're willing, your actual built .ipa or .xcarchive

Runner-flutter_background_fetch.xcarchive

stuartmorgan commented 1 month ago

@christocracy To clarify, you're submitting that example app to the app store and getting an ITMS-91053 warning about NSUserDefaults?

christocracy commented 1 month ago

To clarify

Yes:

"ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryUserDefaults."

christocracy commented 1 month ago

@stuartmorgan As a test, I removed my plugin background_fetch from my pubspec.yaml and re-submitted and still get the ITMS-91053 warning about NSUserDefaults.

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.0
  http: ^1.1.0
  cupertino_icons: ^1.0.5

dev_dependencies:
  test: ^1.5.1
  flutter_driver:
    sdk: flutter

I will bump shared_preferences -> 2.2.2, however looking at the version history, v2.2.2 (5 months ago) predates the existence of the PrivacyInfo.xcprivacy entering the Git repo (Jan 11...about 2 months ago).

stuartmorgan commented 1 month ago

I will bump shared_preferences -> 2.2.2, however looking at the version history, v2.2.2 (5 months ago) predates the existence of the PrivacyInfo.xcprivacy entering the Git repo (Jan 11...about 2 months ago).

The package containing the native code, and therefore the privacy manifest, is shared_preferences_foundation. You need 2.3.5, and currently have 2.3.2 according to your pubspec.lock, so you need to flutter pub upgrade.

christocracy commented 1 month ago

You need 2.3.5, and currently have 2.3.2 according to your pubspec.lock, so you need to flutter pub upgrade.

Done. Sorry, I missed that instruction way above.

pubspec.yaml ```yaml name: background_fetch_example description: Demonstrates how to use the background_fetch plugin. version: 1.1.0+2 environment: sdk: ">=3.3.0 <4.0.0" dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 http: ^1.1.0 cupertino_icons: ^1.0.5 dev_dependencies: test: ^1.5.1 flutter_driver: sdk: flutter flutter: uses-material-design: true ```
pubspec.lock ```yaml # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: _fe_analyzer_shared: dependency: transitive description: name: _fe_analyzer_shared sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted version: "67.0.0" analyzer: dependency: transitive description: name: analyzer sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted version: "6.4.1" args: dependency: transitive description: name: args sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 url: "https://pub.dev" source: hosted version: "2.4.2" async: dependency: transitive description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted version: "2.1.1" characters: dependency: transitive description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted version: "1.3.0" clock: dependency: transitive description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted version: "1.18.0" convert: dependency: transitive description: name: convert sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" url: "https://pub.dev" source: hosted version: "3.1.1" coverage: dependency: transitive description: name: coverage sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" url: "https://pub.dev" source: hosted version: "1.7.2" crypto: dependency: transitive description: name: crypto sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted version: "3.0.3" cupertino_icons: dependency: "direct main" description: name: cupertino_icons sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d url: "https://pub.dev" source: hosted version: "1.0.6" fake_async: dependency: transitive description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" url: "https://pub.dev" source: hosted version: "2.1.2" file: dependency: transitive description: name: file sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted version: "7.0.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" flutter_driver: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" flutter_test: dependency: transitive description: flutter source: sdk version: "0.0.0" flutter_web_plugins: dependency: transitive description: flutter source: sdk version: "0.0.0" frontend_server_client: dependency: transitive description: name: frontend_server_client sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" url: "https://pub.dev" source: hosted version: "3.2.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter source: sdk version: "0.0.0" glob: dependency: transitive description: name: glob sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted version: "2.1.2" http: dependency: "direct main" description: name: http sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted version: "1.2.1" http_multi_server: dependency: transitive description: name: http_multi_server sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" url: "https://pub.dev" source: hosted version: "3.2.1" http_parser: dependency: transitive description: name: http_parser sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" url: "https://pub.dev" source: hosted version: "4.0.2" io: dependency: transitive description: name: io sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" url: "https://pub.dev" source: hosted version: "1.0.4" js: dependency: transitive description: name: js sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted version: "0.6.7" leak_tracker: dependency: transitive description: name: leak_tracker sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" url: "https://pub.dev" source: hosted version: "10.0.0" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 url: "https://pub.dev" source: hosted version: "2.0.1" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 url: "https://pub.dev" source: hosted version: "2.0.1" logging: dependency: transitive description: name: logging sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" url: "https://pub.dev" source: hosted version: "1.2.0" matcher: dependency: transitive description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted version: "0.8.0" meta: dependency: transitive description: name: meta sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted version: "1.11.0" mime: dependency: transitive description: name: mime sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted version: "1.0.5" node_preamble: dependency: transitive description: name: node_preamble sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" url: "https://pub.dev" source: hosted version: "2.0.2" package_config: dependency: transitive description: name: package_config sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" url: "https://pub.dev" source: hosted version: "2.1.0" path: dependency: transitive description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted version: "1.9.0" path_provider_linux: dependency: transitive description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.dev" source: hosted version: "2.2.1" platform: dependency: transitive description: name: platform sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted version: "2.1.8" pool: dependency: transitive description: name: pool sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" url: "https://pub.dev" source: hosted version: "1.5.1" process: dependency: transitive description: name: process sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted version: "5.0.2" pub_semver: dependency: transitive description: name: pub_semver sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted version: "2.1.4" shared_preferences: dependency: "direct main" description: name: shared_preferences sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted version: "2.2.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" url: "https://pub.dev" source: hosted version: "2.2.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted version: "2.3.5" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted version: "2.3.2" shared_preferences_web: dependency: transitive description: name: shared_preferences_web sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted version: "2.3.0" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted version: "2.3.2" shelf: dependency: transitive description: name: shelf sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted version: "1.4.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" url: "https://pub.dev" source: hosted version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e url: "https://pub.dev" source: hosted version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted version: "1.0.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" url: "https://pub.dev" source: hosted version: "2.1.1" source_maps: dependency: transitive description: name: source_maps sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" url: "https://pub.dev" source: hosted version: "0.10.12" source_span: dependency: transitive description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted version: "1.2.0" sync_http: dependency: transitive description: name: sync_http sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" url: "https://pub.dev" source: hosted version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted version: "1.2.1" test: dependency: "direct dev" description: name: test sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f url: "https://pub.dev" source: hosted version: "1.24.9" test_api: dependency: transitive description: name: test_api sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted version: "0.6.1" test_core: dependency: transitive description: name: test_core sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a url: "https://pub.dev" source: hosted version: "0.5.9" typed_data: dependency: transitive description: name: typed_data sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted version: "1.3.2" vector_math: dependency: transitive description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted version: "2.1.4" vm_service: dependency: transitive description: name: vm_service sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted version: "13.0.0" watcher: dependency: transitive description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted version: "1.1.0" web: dependency: transitive description: name: web sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted version: "0.5.1" web_socket_channel: dependency: transitive description: name: web_socket_channel sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" url: "https://pub.dev" source: hosted version: "2.4.4" webdriver: dependency: transitive description: name: webdriver sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted version: "3.0.3" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" url: "https://pub.dev" source: hosted version: "1.2.1" win32: dependency: transitive description: name: win32 sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480" url: "https://pub.dev" source: hosted version: "5.3.0" xdg_directories: dependency: transitive description: name: xdg_directories sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted version: "1.0.4" yaml: dependency: transitive description: name: yaml sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" flutter: ">=3.19.0" ```
ios/Podfile ```ruby # Uncomment this line to define a global platform for your project platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } def flutter_root generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) unless File.exist?(generated_xcode_build_settings_path) raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end File.foreach(generated_xcode_build_settings_path) do |line| matches = line.match(/FLUTTER_ROOT\=(.*)/) return matches[1].strip if matches end raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) flutter_ios_podfile_setup target 'Runner' do flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) end end ```
flutter doctor ```console [✓] Flutter (Channel stable, 3.19.4, on macOS 14.1.1 23B81 darwin-arm64, locale en-CA) [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 15.3) [✓] Chrome - develop for the web [✓] Android Studio (version 2023.2) [✓] Connected device (3 available) [✓] Network resources • No issues found! ```

Confirm whether or not you have added any native code directly to your Runner? (E.g., modified the Swift or Objective-C code in the ios/ directory yourself.)

No.

If you're willing, your actual built .ipa or .xcarchive

Runner-transistor-2.xcarchive

stuartmorgan commented 1 month ago

Thanks for that test. The archive does contain shared_preferences_foundation_privacy.bundle/PrivacyInfo.xcprivacy, which means that the App Store submission process is, at least currently, not picking up that file and factoring it into the checks.

We'll see if we can find out from Apple if this is the intended/final behavior, and also work on explicit documentation about how to manually merge the contents of those files into the app-level manifest in the meantime (a more expanded and discoverable version of 2.ii. in my comment above).

pawlowskim commented 1 month ago

I can confirm, that manually merging Privacy Accessed API Types found in all the PrivacyInfo.xcprivacy from 3rd party libraries can fix the issue with missing Missing API declaration. Although, we are using about ~50 packages in our flutter project, and not each of them have its own PrivacyInfo.xcprivacy. So we are still missing usage of NSPrivacyAccessedAPICategoryDiskSpace.

I have created a dart scripts to merge all found PrivacyInfo.xcprivacy in the project, so at least, it does not need to be done manually.

Is there any guidance how can we track down usage of the 'banned' APIs? Could it be, that apple finds the header: include <sys/stat.h> (which I can find on couple files from the Pods folder) and marks the build as missing accessed api?

christocracy commented 1 month ago

I can confirm, that manually merging Privacy Accessed API Types found in all the PrivacyInfo.xcprivacy from 3rd party libraries can fix the issue.

This is my experience too. Plugin developers had hoped that simply adding this to their Podfile would work:

Pod::Spec.new do |s|
  .
  .
  .
  s.resource_bundles = {'my_plugin_name_privacy' => ['ios/Resources/PrivacyInfo.xcprivacy']}
end

This certainly creates a my_plugin_name_privacy.bundle within the App archive but Apple doesn't seem to be iterating those .bundle and evaluating the PrivacyInfo contained within. it's possible that this is Apple's intended behaviour.

I wonder if something could be added to flutter/packages/flutter_tools/bin/xcode_backend.dart to automatically compose the app's top-level AppPrivacy.xcprivacy by evaluating each of the app's Pods in search of Resources/PrivacyInfo.xcprivacy?

It seems to me that the App Developer is intended to have to manually manage their own App's top-level PrivacyInfo within XCode, manually adding all the required elements from each dependency.

Here is the file-view of an archive I generated. Each of my dependencies' .bundle (containing an PrivacyInfo) is highlighted in blue. Only by manually adding an PrivacyInfo (in red), containing all the required elements, will my App pass Apple's privacy interrogation.

Screenshot 2024-03-27 at 11 31 47 AM
stuartmorgan commented 1 month ago

Is there any guidance how can we track down usage of the 'banned' APIs?

Currently my comment above is the only guidance we have regarding Required Reason APIs at the application-developer level; https://github.com/flutter/flutter/issues/145269 tracks adding more documentation as we figure out what the enforcement behavior is. This isn't a Flutter-specific issue though, so there may be other resources on auditing dependencies for Required Reason APIs that the Flutter team isn't currently aware of.

stuartmorgan commented 1 month ago

I wonder if something could be added to flutter/packages/flutter_tools/bin/xcode_backend.dart to automatically compose the app's top-level AppPrivacy.xcprivacy by evaluating each of the app's Pods in search of Resources/PrivacyInfo.xcprivacy?

It's very unlikely that the tool would create the file, because the file is a declaration to Apple about what the application does and why, and the flutter tool cannot know that. The runner could have arbitrary code added by the app developer using any or all of the required reason APIs, for instance.

Automatically auditing the file against any pod-created bundles, and providing clear guidance about what the tool can tell is definitively missing from the app-level manifest, is something we have considered if it turns out to be necessary.

It seems to me that the App Developer is intended to have to manually manage their own App's top-level PrivacyInfo within XCode, manually adding all the required elements from each dependency.

~We do not know what Apple intends for this case, we only know what the observed behavior of the current enforcement implementation is. As I mentioned in my earlier comment, we are attempting to get clarity on whether that is the intended behavior.~ [Edit April 22, 2024] Please see my comment below for current understanding of the situation.

catgod321 commented 1 month ago

@jmagman Please help me find out which plug-ins are causing privacy compliance issues, thank you very much!

In order to prevent my native code from having a problem, I specially added the picture below just in case.

Privacy manifest details ![隐私合规](https://github.com/flutter/flutter/assets/161576957/02b714e6-0736-435a-82ae-6b0ffdb9f451)

podfile,pubspec.yaml,pubspec.lock.zip

The following is the email Apple sent me:

Although submission for App Store review was successful, you may want to correct the following issues in your next submission for App Store review. Once you've corrected the issues, upload a new binary to App Store Connect.

ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryFileTimestamp. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryUserDefaults. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

stuartmorgan commented 1 month ago

Please help me find out which plug-ins are causing privacy compliance issues, thank you very much!

In order to prevent my native code from having a problem, I specially added the picture below just in case.

Can you clarify what help you are looking for? If you already know exactly how the APIs are being used, then presumably you have already found the calling code, so you can just look at what plugin's directory the code is in.

catgod321 commented 1 month ago

@stuartmorgan I have no way of knowing which plug-ins are causing the privacy policy issues reported to me. I saw that my share_plus plug-in is not the latest version. The latest version has solved the privacy issue. After updating, I found that it still doesn’t work. Now I suspect it is fluttertoast and video_thumbnail. Regarding the problem, I saw that fluttertoast has been submitted on github, but a new version has not been released yet. I dragged the plug-in to the local area, called it as a local plug-in, and then modified it according to the instructions on github, but I still received it. Could the email from Apple be caused by a problem with video_thumbnail? Also, I’m not sure whether my native code could cause this problem.

CarGuo commented 1 month ago

@catgod321 Maybe you can try this sh repo :https://github.com/omarzl/ios_17_required_reason_api_scanner/tree/binary_analyzer

catgod321 commented 1 month ago

@CarGuo I used this tool and got the following results: Used symbols in binary ./Debug-iphoneos/Runner.app/Runner: fstat, lstat, NSUserDefaults, stat Used symbols in binary ./Debug-iphoneos/share_plus/share_plus.framework/share_plus: Used symbols in binary ./Debug-iphoneos/MJExtension/MJExtension.framework/MJExtension: Used symbols in binary ./Debug-iphoneos/SWBaseControl/SWBaseControl.framework/SWBaseControl: NSUserDefaults Used symbols in binary ./Debug-iphoneos/package_info_plus/package_info_plus.framework/package_info_plus: Used symbols in binary ./Debug-iphoneos/SWCustomPresentation/SWCustomPresentation.framework/SWCustomPresentation: Used symbols in binary ./Debug-iphoneos/ReactiveObjC/ReactiveObjC.framework/ReactiveObjC: NSUserDefaults Used symbols in binary ./Debug-iphoneos/Flutter.framework/Flutter: fstat, lstat, mach_absolute_time, NSURLContentModificationDateKey, stat Used symbols in binary ./Debug-iphoneos/Masonry/Masonry.framework/Masonry: Used symbols in binary ./Debug-iphoneos/App.framework/App: Used symbols in binary ./Debug-iphoneos/Pods_Runner.framework/Pods_Runner: Used symbols in binary ./Debug-iphoneos/libwebp/libwebp.framework/libwebp: Used symbols in binary ./Debug-iphoneos/video_thumbnail/video_thumbnail.framework/video_thumbnail: Used symbols in binary ./Debug-iphoneos/SWExtension/SWExtension.framework/SWExtension: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/wakelock_plus.framework/wakelock_plus: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/Masonry.framework/Masonry: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/SWCustomPresentation.framework/SWCustomPresentation: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/video_thumbnail.framework/video_thumbnail: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/ReactiveObjC.framework/ReactiveObjC: NSUserDefaults Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/MJExtension.framework/MJExtension: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/video_player_avfoundation.framework/video_player_avfoundation: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter: fstat, lstat, mach_absolute_time, NSURLContentModificationDateKey, stat Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/CocoaAsyncSocket.framework/CocoaAsyncSocket: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/SWBaseControl.framework/SWBaseControl: NSUserDefaults Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/App.framework/App: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/path_provider_foundation.framework/path_provider_foundation: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/MBProgressHUD.framework/MBProgressHUD: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/share_plus.framework/share_plus: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/SDL2.framework/SDL2: mach_absolute_time Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/DZNEmptyDataSet.framework/DZNEmptyDataSet: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/SWExtension.framework/SWExtension: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/package_info_plus.framework/package_info_plus: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/shared_preferences_foundation.framework/shared_preferences_foundation: NSUserDefaults Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/SWMultipleDelegateProxy.framework/SWMultipleDelegateProxy: Used symbols in binary ./Debug-iphoneos/Runner.app/Frameworks/libwebp.framework/libwebp: Used symbols in binary ./Debug-iphoneos/SDL2.framework/SDL2: mach_absolute_time Used symbols in binary ./Debug-iphoneos/shared_preferences_foundation/shared_preferences_foundation.framework/shared_preferences_foundation: NSUserDefaults Used symbols in binary ./Debug-iphoneos/SWMultipleDelegateProxy/SWMultipleDelegateProxy.framework/SWMultipleDelegateProxy: Used symbols in binary ./Debug-iphoneos/MBProgressHUD/MBProgressHUD.framework/MBProgressHUD: Used symbols in binary ./Debug-iphoneos/video_player_avfoundation/video_player_avfoundation.framework/video_player_avfoundation: Used symbols in binary ./Debug-iphoneos/wakelock_plus/wakelock_plus.framework/wakelock_plus: Used symbols in binary ./Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/CocoaAsyncSocket: Used symbols in binary ./Debug-iphoneos/DZNEmptyDataSet/DZNEmptyDataSet.framework/DZNEmptyDataSet: Used symbols in binary ./Debug-iphoneos/path_provider_foundation/path_provider_foundation.framework/path_provider_foundation: Used symbols in binary ./Debug-iphoneos/permission_handler_apple/permission_handler_apple.framework/permission_handler_apple: NSUserDefaults Used symbols in binary ./Debug-iphoneos/libcppsdk.a: fstat, lstat, stat

CarGuo commented 1 month ago

@catgod321 look like :

SWBaseControl.framework/SWBaseControl: NSUserDefaults

/ReactiveObjC/ReactiveObjC.framework/ReactiveObjC: NSUserDefaults Used symbols in binary ./Debug-iphoneos/Flutter.framework/Flutter: fstat, lstat, mach_absolute_time, NSURLContentModificationDateKey, stat

Flutter.framework/Flutter: fstat, lstat, mach_absolute_time, NSURLContentModificationDateKey, stat

SWBaseControl: NSUserDefaults

SDL2.framework/SDL2: mach_absolute_time

shared_preferences_foundation: NSUserDefaults

SDL2.framework/SDL2: mach_absolute_time

permission_handler_apple: NSUserDefaults Used symbols in binary ./Debug-iphoneos/libcppsdk.a: fstat, lstat, stat

stuartmorgan commented 1 month ago

I have no way of knowing which plug-ins are causing the privacy policy issues reported to me.

If you don't know which plugins are causing the warnings, how did you create the privacy manifest shown in your screenshot?

Also, I’m not sure whether my native code could cause this problem.

If you have written Swift or Obj-C code directly in your project that uses any required reason APIs, then yes.

stuartmorgan commented 1 month ago

Maybe you can try this sh repo :https://github.com/omarzl/ios_17_required_reason_api_scanner/tree/binary_analyzer

@CarGuo binary scanning tools run against build output cannot be used to identify which plugins are statically building code into Runner.

stuartmorgan commented 1 month ago

Please help me find out which plug-ins are causing privacy compliance issues, thank you very much!

Reproing locally with the provided files, I only see evidence of NSUserDefaults usage in Runner, not file timestamp; perhaps the latter comes from app-level code that was not provided. For NSUserDefaults, permission_handler_apple forces static building, so ends up with a privacy manifest in a resource bundle that declares the corresponding usage.

So that's another case of this, which we are exploring options for.

mackymangampo commented 1 month ago

Hi @stuartmorgan I followed your instructions above and create a privacy manifest in my app. but when I submitted it again in IOS Testflight for review its say's I have missing api declarations for NSPrivacyAccessedAPICategoryFileTimestamp, NSPrivacyAccessedAPICategoryDiskSpace, NSPrivacyAccessedAPICategoryUserDefaults and NSPrivacyAccessedAPICategorySystemBootTime but I already add this api types to my PrivacyInfo.xcprivacy

Code in PrivacyInfo.xcprivacy

PrivacyInfo.xcprivacy ![image](https://github.com/flutter/flutter/assets/44796954/21966a09-9cf1-4d37-9996-1de29f849dc5)
pawlowskim commented 1 month ago

@mackymangampo I'm not sure if the top two markers are required, but this is my privacy file (generated from the privacy files from sdks) that fixed Required Api types issues (beside disk space, which I cannot figure out which library is using it):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>NSPrivacyTracking</key>
    <false/>
    <key>NSPrivacyTrackingDomains</key>
    <array></array>
    <key>NSPrivacyCollectedDataTypes</key>
    <array>
      <dict>
        <key>NSPrivacyCollectedDataType</key>
        <string>NSPrivacyCollectedDataTypeOtherDiagnosticData</string>
        <key>NSPrivacyCollectedDataTypeLinked</key>
        <false/>
        <key>NSPrivacyCollectedDataTypeTracking</key>
        <false/>
        <key>NSPrivacyCollectedDataTypePurposes</key>
        <array>
          <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
          <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
        </array>
      </dict>
      <dict>
        <key>NSPrivacyCollectedDataType</key>
        <string>NSPrivacyCollectedDataTypeCrashData</string>
        <key>NSPrivacyCollectedDataTypeLinked</key>
        <false/>
        <key>NSPrivacyCollectedDataTypeTracking</key>
        <false/>
        <key>NSPrivacyCollectedDataTypePurposes</key>
        <array>
          <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
        </array>
      </dict>
      <dict>
        <key>NSPrivacyCollectedDataType</key>
        <string>NSPrivacyCollectedDataTypePerformanceData</string>
        <key>NSPrivacyCollectedDataTypeLinked</key>
        <false/>
        <key>NSPrivacyCollectedDataTypeTracking</key>
        <false/>
        <key>NSPrivacyCollectedDataTypePurposes</key>
        <array>
          <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
        </array>
      </dict>
    </array>
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>1C8F.1</string>
          <string>CA92.1</string>
          <string>C56D.1</string>
        </array>
      </dict>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>35F9.1</string>
        </array>
      </dict>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>C617.1</string>
          <string>0A2A.1</string>
        </array>
      </dict>
    </array>
  </dict>
</plist>
stuartmorgan commented 1 month ago

@mackymangampo I would suggest double checking that you checked the box to include the file in your Runner target. If that's not the issue, you'd need to reach out to Apple, or try a general help resource like Stack Overflow, for help; the core instructions for creating the file come from Apple, not the Flutter team. The scope of this issue is just figuring out how to determine what entries need to be in it for a given set of plugins.

Ultranmus commented 1 month ago

Hey there! I'm encountering a warning from Apple regarding privacy permissions. I know I need to create a privacy manifest and include it as a target runner. However, I'm unsure about which NSPrivacyAccessedAPICategory to use since I'm not directly using platform APIs, but relying on packages like permission_handler and just_audio. Any advice on which category to include?

Required reason list ![Screenshot 2024-04-05 132721](https://github.com/flutter/flutter/assets/140942235/79f8e177-1b25-4ba9-a328-55e4f3347dac)
Ultranmus commented 1 month ago

I'm curious about something regarding privacy manifest files. If I have to create a manifest file for my app, does it matter if other packages in my app, which use those APIs, don't include their own privacy manifest files? Can I just add the required entries to my app's privacy manifest file? Some packages haven't added their manifest files yet, and I'm not sure when they'll do so. Any insights on this? Thanks!

stuartmorgan commented 1 month ago

However, I'm unsure about which NSPrivacyAccessedAPICategory to use since I'm not directly using platform APIs, but relying on packages like permission_handler and just_audio.

Please see this comment for guidance.

Any advice on which category to include?

The only way to know what your application should include would be to look at the privacy manifest and/or code of every plugin your specific application includes. Please see the warning in the comment I linked above.

If I have to create a manifest file for my app, does it matter if other packages in my app, which use those APIs, don't include their own privacy manifest files? Can I just add the required entries to my app's privacy manifest file?

If they are built statically (i.e., if the warnings you received say that the issue is with your Runner binary), your app-level binary currently needs to list all usage reasons for all statically built plugins. It is possible to do that via your own full source (and/or binary, if you have prebuilt transitive dependencies) audit, regardless of whether plugin authors have added manifests. (It continues to be our hope that application authors will not have to create app-level manifests for plugin usage by the time the policy is fully enforced, however.)

If they are built dynamically (in which case the warning would list the relevant framework), they must contain their own manifests.

Ultranmus commented 1 month ago

Any updates from Firebase regarding the inclusion of the privacy manifest in their packages? Also, is there a way to verify everything's correct before submitting to the App Store? I received the warning email after app submission for review. Is there a method to check for issues using Xcode, such as running the app in release mode?

stuartmorgan commented 1 month ago

Any updates from Firebase regarding the inclusion of the privacy manifest in their packages?

Questions about specific third-party packages would need to be directed to the authors of those packages. For that case, https://github.com/firebase/flutterfire/issues/12320 seems to be a relevant issue.

Also, is there a way to verify everything's correct before submitting to the App Store? I received the warning email after app submission for review. Is there a method to check for issues using Xcode, such as running the app in release mode?

I'm not aware of a way to run the actual validation locally, but you'd need to contact Apple support for a definitive answer.

pawlowskim commented 1 month ago

@Ultranmus There is an option to verify application with App Store Connect by archiving it locally and click "Validate App" on specific archive. But I'm not sure if it checks manifests files (I don't have access to distribution keys): https://github.com/crasowas/app_store_required_privacy_manifest_analyser

Beside that, I would recommend this tool for analysing the libraries. It found the missing required API in few minutes (I spent ~2 days so far). Use it against your ios folder in the flutter project https://github.com/crasowas/app_store_required_privacy_manifest_analyser

Ultranmus commented 1 month ago

@pawlowskim Can it be used in window(non apple device)? I tried running on cmd in windows laptop so it was giving this error The term 'sh' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

but after looking into internet i found that i can use this in git bash and then it gives this error sh: privacy_manifest_analyser.sh: No such file or directory

the command i run in git bash was: sh privacy_manifest_analyser.sh "C:\my_projects\flutter_projects\test-app\ios"

Any advice?

stuartmorgan commented 1 month ago

For questions about third-party tools, or about how to actually run validation, please use more general discussion forums. This issue is specifically about how Flutter handles plugin manifests.

stuartmorgan commented 3 weeks ago

Our current understanding is that the solution adopted by the Flutter team's plugins and other plugins in the ecosystem—based on what the CocoaPods community in general has been doing—should work. This involves using resource_bundles to package the manifest (example).

However: We have observed a bug within App Store Connect that is mainly impacting SDKs distributed as static frameworks that declare required reasons in privacy manifests. Due to the bug, developers receive a warning from App Store Connect. We have raised this with Apple, who has acknowledged this issue and confirmed they are working on a fix. We will provide updates when available.

I'll leave this open pending that issue being fully resolved.


Note: If you find this issue because you are an app developer receiving ITMS-91053 warnings, please see https://github.com/flutter/flutter/issues/145269 instead, in particular this comment.