Open stuartmorgan opened 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.
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
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:
- You can read documentation about creating a privacy manifest file.
- Our User Privacy and Data Use page has details about requirements for developers.
- You can watch videos about adopting privacy manifests and signatures for your SDK.
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.
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.
@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
@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.
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.
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).
Questions about specific plugins are off-topic here.
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.)
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
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 inRunner
.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
: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.
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?
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:
s.static_framework = true
) that has declared a privacy manifest, but you're on an older version of that package and you should update.[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!
For Chinese Developers
fluwx: ^4.5.0 tobias: ^3.3.1 jpush_flutter: ^2.5.1 => https://github.com/jpush/jpush-flutter-plugin
Please attach:
pubspec.yaml
andpubspec.lock
ios/Podfile
- 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.)- 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?
Yes, drag in the requested files into a comment to this GitHub issue to attach them.
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.
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
@christocracy To clarify, you're submitting that example app to the app store and getting an ITMS-91053
warning about NSUserDefaults?
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."
@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).
I will bump
shared_preferences
->2.2.2
, however looking at the version history,v2.2.2
(5 months ago) predates the existence of thePrivacyInfo.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
.
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.
shared_preferences
receiving ITMS-91053
:shared_preferences
does NOT receive the warning.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
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).
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?
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.
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.
I wonder if something could be added to
flutter/packages/flutter_tools/bin/xcode_backend.dart
to automatically compose the app's top-levelAppPrivacy.xcprivacy
by evaluating each of the app's Pods in search ofResources/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.
@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.
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.
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.
@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.
@catgod321 Maybe you can try this sh repo :https://github.com/omarzl/ios_17_required_reason_api_scanner/tree/binary_analyzer
@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
@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
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.
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
.
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.
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
@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>
@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.
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?
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!
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.
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?
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.
@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
@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?
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.
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.
[Edit April 22, 2024]:
ITMS-91053
response from Apple, please see this comment.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:
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?