iosxcodeprivacy-manifestios-privacy-settingsrequired-reason-api

Why Apple keeps warning even after I handled the new privacy manifest rule?


Apple's message:

ITMS-91053: Missing API declaration - Your app’s code in the “{app name}” 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 “{app name}” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryDiskSpace. 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 “{app name}” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategorySystemBootTime. 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 “{app name}” 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.

So, I did the following to tackle the issue:

However, when I submitted the new app, Apple still responded with the same warning. My understanding is privacy manifests of the App and SDKs are merged into one (or equivalent). Is that correct? What am I missing then?

Swift Packages and versions

The log from the xcodebuild

[08:11:49]: ▸ Resolved source packages:
[08:11:49]: ▸   GoogleAppMeasurement: https://github.com/google/GoogleAppMeasurement.git @ 10.22.0
[08:11:49]: ▸   GoogleDataTransport: https://github.com/google/GoogleDataTransport.git @ 9.4.0
[08:11:49]: ▸   GTMSessionFetcher: https://github.com/google/gtm-session-fetcher.git @ 3.3.1
[08:11:49]: ▸   UIPiPView: git@github.com:torufuruya/UIPiPView.git @ b3183e7
[08:11:49]: ▸   CwlCatchException: https://github.com/mattgallagher/CwlCatchException.git @ 2.1.1
[08:11:49]: ▸   GoogleSignIn: https://github.com/google/GoogleSignIn-iOS @ 7.1.0
[08:11:49]: ▸   CwlPreconditionTesting: https://github.com/mattgallagher/CwlPreconditionTesting.git @ 2.1.0
[08:11:49]: ▸   AudioKit: https://github.com/AudioKit/AudioKit.git @ 5.5.7
[08:11:49]: ▸   nanopb: https://github.com/firebase/nanopb.git @ 2.30910.0
[08:11:49]: ▸   AppCheck: https://github.com/google/app-check.git @ 10.18.0
[08:11:49]: ▸   Pulse: https://github.com/kean/Pulse @ 1.1.0
[08:11:49]: ▸   Quick: https://github.com/Quick/Quick.git @ 6.1.0
[08:11:49]: ▸   SwiftlySearch: https://github.com/thislooksfun/SwiftlySearch.git @ 1.2.5
[08:11:49]: ▸   GoogleUserMessagingPlatform: https://github.com/googleads/swift-package-manager-google-user-messaging-platform.git @ 2.3.0
[08:11:49]: ▸   swift-video-generator: https://github.com/dev-labs-bg/swift-video-generator.git @ 1.4.1
[08:11:49]: ▸   AdvancedScrollView: https://github.com/dmytro-anokhin/advanced-scrollview.git @ 0.0.6
[08:11:49]: ▸   GTMAppAuth: https://github.com/google/GTMAppAuth.git @ 4.1.1
[08:11:49]: ▸   Firebase: https://github.com/firebase/firebase-ios-sdk.git @ 10.22.0
[08:11:49]: ▸   SwiftyStoreKit: https://github.com/bizz84/SwiftyStoreKit.git @ 0.16.4
[08:11:49]: ▸   Mocker: https://github.com/WeTransfer/Mocker.git @ 3.0.1
[08:11:49]: ▸   leveldb: https://github.com/firebase/leveldb.git @ 1.22.3
[08:11:49]: ▸   Promises: https://github.com/google/promises.git @ 2.4.0
[08:11:49]: ▸   abseil: https://github.com/google/abseil-cpp-binary.git @ 1.2022062300.1
[08:11:49]: ▸   URLImage: https://github.com/dmytro-anokhin/url-image @ 3.1.1
[08:11:49]: ▸   AppAuth: https://github.com/openid/AppAuth-iOS.git @ 1.7.3
[08:11:49]: ▸   SwiftProtobuf: https://github.com/apple/swift-protobuf.git @ 1.25.2
[08:11:49]: ▸   swift-log: https://github.com/apple/swift-log.git @ 1.4.4
[08:11:49]: ▸   gRPC: https://github.com/google/grpc-binary.git @ 1.49.2
[08:11:49]: ▸   Mantis: https://github.com/guoyingtao/Mantis.git @ 2.7.0
[08:11:49]: ▸   Get: https://github.com/kean/Get.git @ 1.0.4
[08:11:49]: ▸   Fakery: https://github.com/vadymmarkov/Fakery @ 5.1.0
[08:11:49]: ▸   Nimble: https://github.com/Quick/Nimble.git @ 11.2.1
[08:11:49]: ▸   GoogleMobileAds: https://github.com/googleads/swift-package-manager-google-mobile-ads.git @ 11.2.0
[08:11:49]: ▸   GoogleUtilities: https://github.com/google/GoogleUtilities.git @ 7.13.1
[08:11:49]: ▸   ImagePickerView: https://github.com/ralfebert/ImagePickerView @ 0.5.0
[08:11:49]: ▸   InteropForGoogle: https://github.com/google/interop-ios-for-google-sdks.git @ 100.0.0

SDKs declaring the reported API categories

The result I grep the API categories directly in the swift package checkout folder: ~/Library/Developer/Xcode/DerivedData/{app name}/SourcePackages/checkouts/

NSPrivacyAccessedAPICategoryFileTimestamp

➜  checkouts grep NSPrivacyAccessedAPICategoryFileTimestamp . -lr
./firebase-ios-sdk/FirebaseDynamicLinks/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/Crashlytics/Resources/PrivacyInfo.xcprivacy
./grpc-binary/grpcpp-Wrapper/Resources/PrivacyInfo.xcprivacy
./grpc-binary/grpc-Wrapper/Resources/PrivacyInfo.xcprivacy
./grpc-binary/openssl-grpc-Wrapper/Resources/PrivacyInfo.xcprivacy
./gtm-session-fetcher/Sources/LogView/Resources/PrivacyInfo.xcprivacy
./GoogleUtilities/GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy

NSPrivacyAccessedAPICategoryDiskSpace

No SDKs. It must have used in the Firebase Crashlytics but it seems to be removed in the latest version.

# 10.22.0
- [fixed] Force validation or rotation of FIDs for FirebaseSessions.
- [changed] Removed calls to statfs in the Crashlytics SDK to comply with Apple Privacy Manifests. This change removes support for collecting Disk Space Free in Crashlytics reports.

I confirmed no other APIs that require this policy listed in the official document (e.g. statfs) were used in any SDKs.

NSPrivacyAccessedAPICategorySystemBootTime

➜  checkouts grep NSPrivacyAccessedAPICategorySystemBootTime . -lr
./firebase-ios-sdk/Crashlytics/Resources/PrivacyInfo.xcprivacy
./grpc-binary/grpcpp-Wrapper/Resources/PrivacyInfo.xcprivacy
./grpc-binary/grpc-Wrapper/Resources/PrivacyInfo.xcprivacy
./grpc-binary/openssl-grpc-Wrapper/Resources/PrivacyInfo.xcprivacy

NSPrivacyAccessedAPICategoryUserDefaults

➜  checkouts grep NSPrivacyAccessedAPICategoryUserDefaults . -lr
./GoogleSignIn-iOS/GoogleSignIn/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/FirebaseDynamicLinks/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/Crashlytics/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/FirebaseCore/Internal/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/FirebaseCore/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/FirebaseAuth/Sources/Resources/PrivacyInfo.xcprivacy
./firebase-ios-sdk/FirebaseRemoteConfig/Swift/Resources/PrivacyInfo.xcprivacy
./gtm-session-fetcher/Sources/Core/Resources/PrivacyInfo.xcprivacy
./GoogleUtilities/GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy

Solution

  • In the end, Apple announced a slight change in its policy statement on April 26th for now.

    As it is also said in the Flutter community, it seems that the set of things that will be enforced starting on May 1st has now been limited to dynamic frameworks.

    So I hope I/we don't receive the warning from Apple and our app will be accepted even after May 1st.