firebase-ios-sdk: App Store Connect warnings that API usage is not being declared by Firebase
Description
I updated to Firebase 10.22.1, but App Store Connect is still warning of APIs such as mach_absolute_time():
ITMS-91053: Missing API declaration - Your app’s code in the “<app>” 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.
System boot time APIs The following APIs for accessing the system boot time require reasons for use. Use the string NSPrivacyAccessedAPICategorySystemBootTime as the value for the NSPrivacyAccessedAPIType key in your NSPrivacyAccessedAPITypes dictionary. systemUptime mach_absolute_time() In your NSPrivacyAccessedAPITypeReasons array, supply the relevant values from the list below. 35F9.1 Declare this reason to access the system boot time in order to measure the amount of time that has elapsed between events that occurred within the app or to perform calculations to enable timers. Information accessed for this reason, or any derived information, may not be sent off-device. There is an exception for information about the amount of time that has elapsed between events that occurred within the app, which may be sent off-device.
Reproducing the issue
I’m using FirebaseAnalyticsWithoutAdIdSupport and FirebaseCrashlytics
Firebase SDK Version
10.22.1
Xcode Version
15.3
Installation Method
Swift Package Manager
Firebase Product(s)
Analytics, Crashlytics
Targeted Platforms
iOS
Relevant Log Output
No response
If using Swift Package Manager, the project’s Package.resolved
Expand Package.resolved
snippet
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "df308b8b46607675f2b9ec8e569109008f9155ce",
"version" : "1.2022062300.1"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3e464dad87dad2d29bb29a97836789bf0f8f67d2",
"version" : "10.18.1"
}
},
{
"identity" : "cocoalumberjack",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git",
"state" : {
"revision" : "4b8714a7fb84d42393314ce897127b3939885ec3",
"version" : "3.8.5"
}
},
{
"identity" : "collectionconcurrencykit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
"state" : {
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
"version" : "0.2.0"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
"state" : {
"revision" : "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c",
"version" : "1.8.1"
}
},
{
"identity" : "devicekit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/devicekit/DeviceKit.git",
"state" : {
"revision" : "fe41d18eccd92a115cffaa35dfff03018c67e635",
"version" : "5.2.2"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "be49849dcba96f2b5ee550d4eceb2c0fa27dade4",
"version" : "10.22.1"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "482cfa4e5880f0a29f66ecfd60c5a62af28bd1f0",
"version" : "10.22.1"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "a637d318ae7ae246b02d7305121275bc75ed5565",
"version" : "9.4.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "26c898aed8bed13b8a63057ee26500abbbcb8d55",
"version" : "7.13.1"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "ea4cb5cc0c39c732b85386263116d2e2fdbbdc61",
"version" : "1.49.2"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "76135c9f4e1ac85459d5fec61b6f76ac47ab3a4c",
"version" : "3.3.1"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
"version" : "100.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "43aaef65e0c665daadf848761d560e446d350d3d",
"version" : "1.22.4"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "sourcekitten",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/SourceKitten.git",
"state" : {
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
"version" : "0.34.1"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
"version" : "1.2.3"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log",
"state" : {
"revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
"version" : "1.5.4"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8",
"version" : "1.25.2"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
"version" : "509.0.2"
}
},
{
"identity" : "swiftlint",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/SwiftLint",
"state" : {
"revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
"version" : "0.54.0"
}
},
{
"identity" : "swiftytexttable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
"state" : {
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
"version" : "0.9.0"
}
},
{
"identity" : "swxmlhash",
"kind" : "remoteSourceControl",
"location" : "https://github.com/drmohundro/SWXMLHash.git",
"state" : {
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
"version" : "7.0.2"
}
},
{
"identity" : "yams",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/Yams.git",
"state" : {
"revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
"version" : "5.0.6"
}
}
],
"version" : 2
}
If using CocoaPods, the project’s Podfile.lock
Expand Podfile.lock
snippet
Replace this line with the contents of your Podfile.lock!
About this issue
- Original URL
- State: closed
- Created 4 months ago
- Reactions: 74
- Comments: 73 (20 by maintainers)
As far as I can tell, it’s entirely on Apple’s side.
The issue:
When you use SPM (or CocoaPods if it’s set to use static linking), the code for your dependencies is all placed directly in the main binary for the app. But the corresponding PrivacyInfo.xcprivacy files can’t all be placed directly in the main app bundle without clashing, and there’s no automatic tooling for merging those into a single PrivacyInfo.xcprivacy, so instead a resource bundle (.bundle) for each package is created and nested in the .app, and the PrivacyInfo.xcprivacy file for each package is placed in its corresponding .bundle.
This is in contrast with how things are structured when dynamically linked .frameworks are used. In that scenario, the .app binary contains just the top-level app code, and there’s a .framework bundle for each dependency that contains both the binary for its code and its PrivacyInfo.xcprivacy file (along with any other resources).
The tooling that Apple is using in its App Store Connect privacy manifest validator seems to only look at the PrivacyInfo.xcprivacy files that are placed directly in the main app bundle or directly in a .framework. It doesn’t actually look at the nested resource bundles created in the static linking case.
So effectively Apple is ignoring the privacy manifests for all dependencies when you use SPM, Apple’s first-party recommended way of managing dependencies. Which is pretty maddening, and makes it seem like the team that created the App Store Connect “required reasons api” validator didn’t actually talk to the people working the privacy manifest support for SPM/Xcode.
Meanwhile, as far as I know, Apple still hasn’t publicly admitted this is the case, or acknowledged if this bug/limitation is something that they intend to address on their end.
If they don’t address it, the only current workaround is to manually create your own top-level PrivacyInfo.xcprivacy files for your apps, and include in them a merging of the contents of the PrivacyInfo.xcprivacy files from your dependencies (in particular the
NSPrivacyAccessedAPITypes
sections).But if that’s the expected way of doing things, I think it really undermines the intended purpose of privacy manifests.
Hi @Digipom, thanks for reporting and apologies for the trouble. I was able to reproduce the above behavior. There appears to be an issue with how R.R. API usage attribution is validated when using static frameworks. If you inspect the app bundle, you should see privacy manifests from Firebase that justify this API usage. But since the SDK symbols are statically linked into the main app, the SDK resource bundles do not seem to be taken into account when checking for R.R. API usage.
We have filed a feedback with Apple and I will keep this thread updated.
Is this still being looked into?
Updating to
10.24.0
removed the warning forNSPrivacyAccessedAPICategorySystemBootTime
, but we are still getting warnings forNSPrivacyAccessedAPICategoryDiskSpace
andNSPrivacyAccessedAPICategoryFileTimestamp
.Unfortunately it isn’t clear from Apple’s messaging if it is coming from Firebase or from another third party library in our project.
This issue is still open. They closed a duplicate issue.
EDIT: The number of subscribers on this issue has gotten fairly large so let’s all take extra care to not spam the thread ❤️
@ncooke3 Thank you for your answer. I have a privacy manifest included to my project. In this manifest I declared the reason of using the UserDefaults API. Even if I have this privacy manifest - which is silenced the warning about the userdefaults - I still get warning about NSPrivacyAccessedAPICategorySystemBootTime and NSPrivacyAccessedAPICategoryFileTimestamp which are used by firebase. I would include these to my privacy manifest, but the problem is that I don’t know the exact relevant reasons since I don’t know how firebase uses these APIs exactly…
Hi all, even with 10.24.0 is have the same issue
Thanks, @adrianvintu, that is the behavior I’m seeing. I was also able to reproduce when depending on SwiftPM targets from source. We have filed two feedback tickets with Apple for this (they aren’t publicly visible but are FB13691093 & FB13687188). I don’t yet have a response to share, but will update accordingly!
I think there’s an issue with GoogleUtilities not having a privacy manifest for each target: https://github.com/google/GoogleUtilities/issues/150
(Relevant post from Apple Engineer: https://forums.developer.apple.com/forums/thread/742221?answerId=776008022#776008022)
Hi, I’m experiencing the similar issue, having a warning from Apple regarding
NSPrivacyAccessedAPICategoryDiskSpace
I’ve looked through Privacy manifest included with Firebase SDK 10.24.0, and I couldn’t find any declaration of using these APIs
Knowing there is a feature in
Crashlytics
backend that shows available space on the device during the crash, I assume that issue is onFirebase
side of using disk space API calls without declaring them in Privacy manifest. If I’m correct, hope it could be addresses in the next releases.PS: we are using dynamic linking with cocoapods
I’ve installed Firebase 10.23.0 for iOS via CocoaPods. When I search in my Xcode project for the mentioned privacy reason “3D61.1” in your article, I get no matches. However, I do get a match for another reason for
NSPrivacyAccessedAPICategorySystemBootTime
; “35F9.1”:This reason does not demand user permission by Apple.
I did verify all other reasons and they all do comply. Google has even removed collecting Disk Space (which was shown at the “Data” tab of a Crashlytics log), so there is no need to report a reason for
NSPrivacyAccessedAPICategoryDiskSpace
.Hi,
Do you know if these new privacy declarations mean that apps would have to explicitly ask for permission to report crashes via Firebase Crashlytics?
For reference NSPrivacyAccessedAPICategorySystemBootTime
3D61.1 Declare this reason to include system boot time information in an optional bug report that the person using the device chooses to submit. The system boot time information must be prominently displayed to the person as part of the report.
Information accessed for this reason, or any derived information, may be sent off-device only after the user affirmatively chooses to submit the specific bug report including system boot time information, and only for the purpose of investigating or responding to the bug report.
Firebase Firestore and GTMSessionFetcher are missing the FileTimeStampAPI key in their XCPrivacy file. They use TimeStamp API’s (stat) and does not declare them. I cannot release my app until these are resolved as our release date is after May 1st.
I’m still getting alerts with 10.23.1.
FIrebaseAnalytics is a statically linked binary.
I use CocoaPods to integrate Crashlytics included in Firebase Apple SDK 10.22.0, and when submitting for review on the App Store, I encountered the same warning as this issue.
I statically link the framework with the following settings in the Podfile.
Although this issue is tagged as Swift Package Manager, is it the same issue that occurred in my environment when using CocoaPods?
I see a lot of apps on the interwebs are using Firebase and Google Maps are complaining about this, mainly that Apple does not merge the privacy codes.
Any news are welcome.
It seems like things are working as intended now, so I believe this has been addressed as of the May 1 deadline. I’m going to close this issue now. Please feel free to open a new issue if anything else comes up.
@nczoltan, yes, that is expected. App Store Connect’s R.R. API validation logic still isn’t processing privacy manifests from frameworks. It only accounts for the privacy manifest in the root of the app, which explains why @Digipom’s approach suppresses the warnings.
Yes. The same issue occurs with CocoaPods when linking statically versus dynamically. As discussed above, as far as we can tell, this is an Apple issue, so it may help to send additional feedback to Apple.
We will at some point, but wanted to preserve the optionality for now, since 1.22.2 is still functional and anyone who cares about the warning can update.
@ncooke3 I’ve been reading Apple’s documentation and think I might have a clue.
I saw you made a new release on the forked leveldb this repo uses that adds the PrivacyInfo file. Firebase does not use this version yet though.
Do you think updating firebase to use leveldb 1.22.4 would solve the issue?
The issue was on App Store Connect’s validation tooling-- it appeared to be ignoring SDK’s privacy manifests for statically linked SDKs. In Firebase 10.25.0, some R.R. API were removed to lessen the surface area that exposed this problem.
I submitted a build on April 30th (it was a patch to the live version that didn’t have any privacy manifests at all) and got it approved and available on the AppStore, and didn’t get any warning email. Paul mentioned here that Apple put some news up on the 26th April that suggests it will only affect new apps and apps that add dependencies on the list after the 1st of May, so it looks like existing apps with existing dependencies are not affected by this change in requirements. (but will be in some future announcement by Apple)
Maybe the warning is still delayed, but I was able to release a new build to TestFlight with 10.25.0 and I didn’t get any warnings. Was there actually an issue on Firebase’s side that was fixed with the move to 10.25.0? Will update in case the warning does come through.
Hi, I think I have the same problem , using cocoadpods to, even if firebase sdk, crashlytics, messaging and other is up to date I still have the error for NSPrivacyAccessedAPICategoryDiskSpace and NSPrivacyAccessedAPICategorySystemBootTime. I dont know what to do. Did I need to add reason type in my privacy that I think can match the sdk, or is it a bad Idea. Is Apple really gonna block new version for app already in the store may 1st ?
Hi @fannt & @adrianvintu, Crashlytics’s disk space reporting feature was removed in 10.22.0, so the warning should not be originating from Crashlytics on versions 10.22.0 or later.
Easy: just search in the subfolders of your project for
PrivacyInfo.xcprivacy
file. You will get the privacy infos for severar packages, like firebase and google. See attached sameple firebase ns.txtThen gather the NS declarations from the different files, and merge them when needed, like below
@adrianvintu, on the right hand side of the first image, no targets are checked for the Target Membership section. I suspect that if you checked the boxes for Runner and Share Extension, the privacy manifest would be included in the app bundle when archiving.
Hi @crleonard, 10.24.0 just finished releasing.
No, I think the ticket I filed is sufficient, but thank you. I’ll continue to keep this bug updated for when I receive an official response on the ticket we have filed.
Correct:
Which makes it super weird that the binary scanner tool is finding symbols there…
If I navigate to that file in Finder, it’s a 35kb file.
Xcode 15.3 (15E204a)
This proofs that the implementation of the Privacy files within the Firebase SDK is working as expected. Are you 100% sure that the 2 remaining ones are not related to the code of your own app, or any other 3rd party library?
Our own app also had still 3 warnings remaining. Among them
NSPrivacyAccessedAPICategoryUserDefaults
, which makes sense since we useNSUserDefaults
in our own app. The Apple support page which is referred in the email from App Store Connect, provides sufficient information about functions and methods that you can just search for in your Xcode project. For example forNSPrivacyAccessedAPICategorySystemBootTime
it showssystemUptime
. When searching for this in our code, we found calls to[[NSProcessInfo processInfo] systemUptime]
in our own logic. This means that we are responsible to add a Privacy file ourselves, for example as instructed here. Don’t forget to assign the added Privacy file to the proper target(s).After submitting the new Build with this Privacy file, we didn’t receive the email from App Store Connect anymore ✅
When we uploaded a build with recent added usage of Firebase Messaging from a notification extension to TestFlight, we got these reported for the extension:
NSPrivacyAccessedAPICategoryFileTimestamp NSPrivacyAccessedAPICategoryUserDefaults
There were no other edits to the notification extension, so what I assume is these are related to FirebaseMessaging, but I couldn’t see them mentioned here.
Same issue here with CocoaPods, I upgraded a few days ago Firebase to 10.23.1 and submitted for review and we still have the same warnings. Will SwiftPM fix also solve the issue when distributing the SDK through CocoaPods?
Possibly related: https://github.com/apple/swift-package-manager/issues/7317