ITMS-91064: NSPrivacyTracking and NSPrivacyTrackingDomains must agree in every privacy manifest (true needs domains, domains need true); check, scan and privacy-manifest fail on either mismatch with the exact ITMS text; App Privacy tracking no longer demands the app manifest's true: SDK manifests that declare tracking (Pods, frameworks, SwiftPM, Carthage, plugins, the built IPA) are info, known tracking SDKs info, else a warning; privacy-manifest --propose writes true only with appPrivacy.trackingDomains; apple upload checks every manifest in the IPA (XML or binary) before any network call, apple build after the export. Pitfall 29
This commit is contained in:
parent
b7bfe89151
commit
c8213be2b6
19 changed files with 631 additions and 44 deletions
|
|
@ -35,7 +35,8 @@
|
|||
// testing for personal accounts, Play metadata, ads, payments, impersonation) are in play-rules.ts with their sources.
|
||||
import type { ShipConfig } from '../config';
|
||||
import { allSubscriptions } from '../subscriptions';
|
||||
import { LISTED_SDKS, REQUIRED_REASON_APIS } from '../privacy-manifest';
|
||||
import { sdkOfProjectPath } from '../privacy-files';
|
||||
import { itms91064, LISTED_SDKS, REQUIRED_REASON_APIS, trackingIssue, trackingProblem } from '../privacy-manifest';
|
||||
import { IOS_PERMISSIONS, vaguePurpose } from './permissions';
|
||||
import { playRules } from './play-rules';
|
||||
import { grep, grepOwn, type Hit, lineOf, type ProjectFacts } from './project';
|
||||
|
|
@ -304,6 +305,17 @@ export function scanRules(inp: ScanInput): ScanFinding[] {
|
|||
else if (apiHits.length)
|
||||
add({ rule: 'privacy-manifest', guideline: 'Privacy manifest (ITMS-91053)', store: 'apple', severity: 'blocker', title: `Required-reason APIs used but not declared in PrivacyInfo.xcprivacy: ${apiHits.map(h => h.text.split(':')[0]).join(', ')}`, evidence: apiHits.slice(0, 4),
|
||||
fix: 'Add each category to NSPrivacyAccessedAPITypes with an approved reason code (for app data in UserDefaults: CA92.1).', skill: 'privacy-manifest', ref: 'https://developer.apple.com/documentation/bundleresources/privacy-manifest-files/describing-use-of-required-reason-api' });
|
||||
// ITMS-91064: NSPrivacyTracking and NSPrivacyTrackingDomains must agree (true + empty list was refused at upload too)
|
||||
for (const m of p.privacyManifests) {
|
||||
const problem = trackingProblem(m);
|
||||
if (!problem) continue;
|
||||
const sdk = sdkOfProjectPath(m.path);
|
||||
add({ rule: 'privacy-manifest', guideline: 'Privacy manifest (ITMS-91064)', store: 'apple', severity: 'blocker',
|
||||
title: problem === 'true-without-domains' ? `${m.path}: NSPrivacyTracking true with an empty NSPrivacyTrackingDomains (Apple refuses the build: ITMS-91064)` : `${m.path}: NSPrivacyTrackingDomains listed with NSPrivacyTracking ${m.tracking === false ? 'false' : 'missing'} (Apple refuses the build: ITMS-91064)`,
|
||||
evidence: [{ file: m.path, line: 1, text: problem === 'true-without-domains' ? 'NSPrivacyTracking true, NSPrivacyTrackingDomains empty' : `NSPrivacyTrackingDomains: ${m.trackingDomains.join(', ')}` }],
|
||||
fix: `${trackingIssue(m, sdk)!.split(' Fix: ')[1]} Apple: ${itms91064('PrivacyInfo.xcprivacy')}`, skill: 'privacy-manifest',
|
||||
ref: 'https://developer.apple.com/documentation/bundleresources/privacy-manifest-files' });
|
||||
}
|
||||
for (const s of p.sdks) {
|
||||
if (!s.sdk.manifestSince) continue;
|
||||
for (const d of s.deps.filter(x => (x.eco === 'cocoapods' || x.eco === 'spm') && x.version)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue