# iOS Privacy Manifests ve App Tracking: 2026 Compliance Rehberi
Apple'ın privacy-first yaklaşımı her yıl yeni compliance gereklilikler getiriyor. 2023'te başlayan Privacy Manifests zorunluluğu, 2024'te SDK manifest kontrolüyle genişledi, 2025'te binary validation eklendi ve 2026'da App Store submission süreci daha da katılaştı. Artık bir app submit etmek için sadece kodu yazmak yetmiyor — kullandığın her API'nin neden kullanıldığını, hangi verileri topladığını ve hangi third-party SDK'ların hangi domain'lere bağlandığını beyanda bulunman gerekiyor.
Bu rehber, Privacy Manifests yapısını, Required Reason API kategorilerini, SDK manifest composition sürecini ve ATT (App Tracking Transparency) best practice'lerini 2026 güncel durumla anlatıyor. App Store rejection'dan kaçınmak için gerçekten ne gerektiğini, neyin yanlış yapıldığını ve production deneyiminden öğrenilenleri paylaşıyor.
2026'da yeni gelen gereklilik: App Store Connect artık third-party SDK binary'lerini statik analiz ile tarayıp manifest'te declare edilmemiş API kullanımlarını otomatik tespit ediyor. Bu da demek oluyor ki dependency'lerini körce ekleme dönemi bitti — her CocoaPod, her SPM package, her XCFramework inceleme altında.
💡 Pro Tip: App Store'a submit etmeden önce xcrun privacy-manifest CLI aracını çalıştır (Xcode 15.3+). Bu araç, uygulamanın kullandığı Required Reason API'ları otomatik tespit eder ve PrivacyInfo.xcprivacy ile karşılaştırır. CI pipeline'ına ekle — submission öncesi otomatik uyarı alırsın.İçindekiler
- Privacy Manifest Nedir
- PrivacyInfo.xcprivacy Yapısı
- NSPrivacyAccessedAPITypes: 4 Kategori
- NSPrivacyCollectedDataTypes
- NSPrivacyTrackingDomains
- SDK Manifest Composition
- Third-Party Binary Validation
- ATT UX Best Practices
- Consent Management Platforms
- IDFA Alternatifleri 2026
- 2026 App Store Rejection Sebepleri
- Compliance Checklist
Privacy Manifest Nedir
Privacy Manifest, bir iOS uygulamasının veya SDK'ının hangi privacy-sensitive API'ları kullandığını ve neden kullandığını beyan ettiği yapılandırma dosyasıdır. PrivacyInfo.xcprivacy adıyla proje root'una veya SDK bundle'ına eklenir.
Neden zorunlu? Apple, üçüncü taraf SDK'ların uygulama geliştiricilerin habersizce privacy-sensitive API kullanmasının önüne geçmek istiyor. "Fingerprinting" olarak adlandırılan — kullanıcıyı tanımlamak için sistem bilgilerini birleştirme — yöntemi bu sayede engellenmeye çalışılıyor.
Kim için geçerli?
- Her iOS/iPadOS/macOS/tvOS/watchOS uygulaması
- App Store'da dağıtılan SDK'lar (CocoaPods, SPM, XCFramework)
- Third-party framework vendor'ları
Hangi durumlarda rejection alırsın?
- Required Reason API kullanıyorsun ama manifest'te declare etmemişsin
- Declare ettiğin reason, gerçek kullanım amacıyla eşleşmiyor
- Kullandığın third-party SDK'nın kendi manifest'i eksik veya yanlış
- Tracking domain beyan edilmemiş ama SDK o domain'e bağlanıyor
PrivacyInfo.xcprivacy Yapısı
PrivacyInfo.xcprivacy bir property list (plist) dosyası. Xcode'da "Privacy Manifest File" template'i ile oluşturulur.
xml
123 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">4 5 6 7 NSPrivacyTracking 8 9 10 11 NSPrivacyTrackingDomains 12 13 14 15 16 17 NSPrivacyAccessedAPITypes 18 19 20 NSPrivacyAccessedAPIType 21 NSPrivacyAccessedAPICategoryUserDefaults 22 NSPrivacyAccessedAPITypeReasons 23 24 CA92.1 25 26 27 28 NSPrivacyAccessedAPIType 29 NSPrivacyAccessedAPICategoryFileTimestamp 30 NSPrivacyAccessedAPITypeReasons 31 32 C617.1 33 34 35 36 37 38 NSPrivacyCollectedDataTypes 39 40 41 NSPrivacyCollectedDataType 42 NSPrivacyCollectedDataTypeEmailAddress 43 NSPrivacyCollectedDataTypeLinked 44 45 NSPrivacyCollectedDataTypeTracking 46 47 NSPrivacyCollectedDataTypePurposes 48 49 NSPrivacyCollectedDataTypePurposeAppFunctionality 50 51 52 5354Dosya konumu:
- App:
[AppName]/PrivacyInfo.xcprivacy(target'ın root'unda) - SDK: Framework/XCFramework bundle içinde
Xcode'da ekleme:
- File → New → File from Template → iOS → Privacy Manifest
- Target membership'te uygulamanı seç
- Xcode otomatik privacy nutrition label güncelliyor
NSPrivacyAccessedAPITypes: 4 Kategori
Apple, "Required Reason API" olarak 4 ana kategori tanımladı. Bu API'lara erişmek için geçerli bir reason kodu declare etmek zorundasın.
Kategori 1: UserDefaults
NSPrivacyAccessedAPICategoryUserDefaults — UserDefaults API'sına erişim.
swift
1// Bu kullanımlar manifest gerektirir:2UserDefaults.standard.set(value, forKey: key)3UserDefaults.standard.value(forKey: key)4UserDefaults(suiteName: "group.com.example")5 6// Geçerli reason kodları:7// CA92.1 — Sadece bu uygulamanın kendi state'ini yönetmek için8// 1C8F.1 — App group container paylaşımı için9// C56D.1 — Kullanıcı tarafından talep edilen içerik sağlamak içinxml
1 2 NSPrivacyAccessedAPIType 3 NSPrivacyAccessedAPICategoryUserDefaults 4 NSPrivacyAccessedAPITypeReasons 5 6 CA92.1 7 8Kategori 2: File Timestamp
NSPrivacyAccessedAPICategoryFileTimestamp — Dosya oluşturma/değiştirme tarihine erişim.
swift
1// Bu kullanımlar manifest gerektirir:2let attributes = try FileManager.default.attributesOfItem(atPath: path)3let modDate = attributes[.modificationDate]4let url = URL(fileURLWithPath: path)5let resourceValues = try url.resourceValues(forKeys: [.contentModificationDateKey])xml
1 2 NSPrivacyAccessedAPIType 3 NSPrivacyAccessedAPICategoryFileTimestamp 4 NSPrivacyAccessedAPITypeReasons 5 6 7 C617.1 8 9Kategori 3: System Boot Time
NSPrivacyAccessedAPICategorySystemBootTime — Cihazın ne zaman başlatıldığı bilgisi. Fingerprinting için kullanılabildiğinden en kısıtlı kategori.
swift
1// Bu kullanımlar manifest gerektirir:2ProcessInfo.processInfo.systemUptime3clock_gettime(CLOCK_MONOTONIC, ×pec)4mach_absolute_time()5// CFAbsoluteTimeGetCurrent() NOT burada değil, sadece boot-time relativexml
1 2 NSPrivacyAccessedAPIType 3 NSPrivacyAccessedAPICategorySystemBootTime 4 NSPrivacyAccessedAPITypeReasons 5 6 7 35F9.1 8 9Kategori 4: Disk Space
NSPrivacyAccessedAPICategoryDiskSpace — Kullanılabilir disk alanı bilgisi.
swift
1// Bu kullanımlar manifest gerektirir:2let values = try URL(fileURLWithPath: "/").resourceValues(3 forKeys: [.volumeAvailableCapacityForImportantUsageKey]4)5let available = values.volumeAvailableCapacityForImportantUsagexml
1 2 NSPrivacyAccessedAPIType 3 NSPrivacyAccessedAPICategoryDiskSpace 4 NSPrivacyAccessedAPITypeReasons 5 6 7 E174.1 8 9NSPrivacyCollectedDataTypes
Uygulamanın topladığı tüm veri türleri declare edilmeli. Bu, App Store privacy nutrition label'ını oluşturur.
xml
1NSPrivacyCollectedDataTypes 2 3 4 5 NSPrivacyCollectedDataType 6 NSPrivacyCollectedDataTypeEmailAddress 7 8 NSPrivacyCollectedDataTypeLinked 9 10 11 NSPrivacyCollectedDataTypeTracking 12 13 14 NSPrivacyCollectedDataTypePurposes 15 16 NSPrivacyCollectedDataTypePurposeAppFunctionality 17 18 19 20 21 22 NSPrivacyCollectedDataType 23 NSPrivacyCollectedDataTypeProductInteraction 24 NSPrivacyCollectedDataTypeLinked 25 26 NSPrivacyCollectedDataTypeTracking 27 28 NSPrivacyCollectedDataTypePurposes 29 30 NSPrivacyCollectedDataTypePurposeAnalytics 31 32 33Ana veri kategorileri:
Kategori | Key | Örnek |
|---|---|---|
İletişim Bilgisi | `NSPrivacyCollectedDataTypeEmailAddress` | E-posta |
Sağlık | `NSPrivacyCollectedDataTypeHealth` | Kalp atışı |
Konum | `NSPrivacyCollectedDataTypePreciseLocation` | GPS |
İdentifierlar | `NSPrivacyCollectedDataTypeDeviceID` | IDFA |
Kullanım Verileri | `NSPrivacyCollectedDataTypeProductInteraction` | Tıklamalar |
Teşhis | `NSPrivacyCollectedDataTypeCrashData` | Crash log |
NSPrivacyTrackingDomains
Eğer NSPrivacyTracking = true ise, tracking için kullanılan tüm domain'ler listelenmelidir. ATT permission alınmadan bu domain'lere bağlantı iOS tarafından engellenir.
xml
1NSPrivacyTracking 2 3NSPrivacyTrackingDomains 4 5 analytics.yourdomain.com 6 track.adnetwork.com 7 events.mmprovider.com 8Tracking domain nedir? Apple'ın tanımına göre, kullanıcının uygulamalar ve web siteleri arasında takip edilmesi amacıyla kullanılan domain. Şüpheli durumlarda tracking olarak declare et — yanlış bir false declaration, App Review'dan geçse bile gelecekte rejection sebebi olur.
swift
1// ATT durumuna göre tracking domain davranışı2import AppTrackingTransparency3 4func checkTrackingPermission() async {5 // iOS, ATT izni olmadan tracking domain'lere bağlantıyı engeller6 let status = ATTrackingManager.trackingAuthorizationStatus7 8 switch status {9 case .authorized:10 // Tracking domain'ler erişilebilir, IDFA kullanılabilir11 enableFullAnalytics()12 case .denied, .restricted:13 // Tracking domain'ler bloklu — sadece non-tracking analytics14 enablePrivacyAnalytics()15 case .notDetermined:16 // İzin henüz sorulmadı — sadece gerekli features çalışır17 enableBasicFunctionality()18 @unknown default:19 enableBasicFunctionality()20 }21}SDK Manifest Composition
Bir uygulama, kullandığı tüm SDK'ların manifest'lerini otomatik merge eder. Ancak bazı durumlarda manuel müdahale gerekir.
Otomatik composition (Xcode 15+):
Xcode, app archive oluştururken tüm dependency'lerin PrivacyInfo.xcprivacy dosyalarını toplar ve app'in privacy report'unu oluşturur. Product → Generate Privacy Report ile kontrol edebilirsin.
swift
1// Privacy Report örneği (Xcode menüsünden):2MyApp Privacy Report3├── MyApp(App)4│ └── NSPrivacyAccessedAPITypes: UserDefaults(CA92.1)5├── Alamofire(Framework)6│ └── NSPrivacyAccessedAPITypes: SystemBootTime(35F9.1)7├── Firebase Analytics(Framework)8│ ├── NSPrivacyTracking: true9│ ├── NSPrivacyTrackingDomains: [app-measurement.com, ...]10│ └── NSPrivacyAccessedAPITypes: UserDefaults, FileTimestamp, SystemBootTime11└── SnapKit(Framework)12 └── (No privacy manifest — WARNING!)Manifest olmayan SDK için ne yaparsın?
swift
1// Eğer third-party SDK manifest içermiyorsa:2// 1. Vendor'a issue aç (GitHub)3// 2. Geçici olarak app'in manifest'ine SDK'nın kullandığı API'ları ekle4// 3. App Review için "SDK manifest bekleniyoruz" notunu Review Notes'a ekle5 6// App'in PrivacyInfo.xcprivacy'ye SDK adına ek:7// Bu doğru yaklaşım DEĞİL ama App Review geçiş için geçiciSPM ile manifest:
swift
1// Package.swift — SDK geliştiriyorsan2let package = Package(3 name: "MyAnalyticsSDK",4 products: [...],5 targets: [6 .target(7 name: "MyAnalyticsSDK",8 resources: [9 // PrivacyInfo.xcprivacy dosyasını bundle'a ekle10 .process("Resources/PrivacyInfo.xcprivacy")11 ]12 )13 ]14)Third-Party Binary Validation
2026'da App Store Connect, binary statik analizi ile manifest beyannamesini çapraz kontrol ediyor. Bu, önceden görülmemiş bir katmandır.
Nasıl çalışır?
- Submit edilmiş IPA içindeki tüm binary'ler (app + framework'ler) taranır
- Required Reason API çağrıları tespit edilir
PrivacyInfo.xcprivacyile karşılaştırılır- Eşleşmeyen API'lar için otomatik warning veya rejection gelir
Lokal kontrol (CI/CD için):
bash
1# Xcode 15.3+ ile gelen privacy manifest validator2xcrun privacy-manifest verify --app MyApp.ipa --manifest MyApp/PrivacyInfo.xcprivacy3 4# Çıktı örneği:5# WARNING: NSPrivacyAccessedAPICategorySystemBootTime6# Used in: Frameworks/ThirdPartySDK.framework7# Not declared in manifest8#9# PASS: NSPrivacyAccessedAPICategoryUserDefaults10# Declared reason: CA92.111# Found usage in: MyApp binaryGitHub Actions CI entegrasyonu:
yaml
1# .github/workflows/privacy-check.yml2name: Privacy Manifest Check3on: [pull_request]4 5jobs:6 privacy-check:7 runs-on: macos-158 steps:9 - uses: actions/checkout@v410 - name: Build Archive11 run: |12 xcodebuild archive -scheme MyApp -destination "generic/platform=iOS" -archivePath build/MyApp.xcarchive13 - name: Verify Privacy Manifest14 run: |15 xcrun privacy-manifest verify --archive build/MyApp.xcarchive || exit 1ATT UX Best Practices
App Tracking Transparency popup'ının zamanlaması ve UX'i, opt-in oranını dramatik etkiler. Yanlış zamanlama %20-30'lara düşen opt-in anlamına gelir. Doğru yapıldığında %60-70'e çıkabilir.
Temel kural: Önce değer sun, sonra izin iste.
swift
1import AppTrackingTransparency2import AdSupport3 4class TrackingManager {5 // Singleton pattern6 static let shared = TrackingManager()7 private init() {}8 9 // ATT dialog'u zamanlama ile göster10 func requestTrackingIfNeeded() async {11 // İzin durumunu kontrol et12 guard ATTrackingManager.trackingAuthorizationStatus == .notDetermined else {13 return14 }15 16 // Onboarding tamamlandıktan SONRA, belirli bir delay ile17 // Kullanıcı uygulamayı deneyimledi — şimdi istemek daha mantıklı18 try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 saniye delay19 20 let status = await ATTrackingManager.requestTrackingAuthorization()21 handleTrackingStatus(status)22 }23 24 private func handleTrackingStatus(_ status: ATTrackingManager.AuthorizationStatus) {25 switch status {26 case .authorized:27 // IDFA kullanılabilir28 let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString29 AnalyticsManager.shared.configure(idfa: idfa)30 case .denied, .restricted:31 // Privacy-safe analytics: aggregated, non-identified32 AnalyticsManager.shared.configurePrivacyMode()33 case .notDetermined:34 break35 @unknown default:36 break37 }38 }39}Pre-permission screen (custom dialog önce):
swift
1// Önce kendi açıklama ekranını göster, sonra system dialog'u aç2struct TrackingPermissionView: View {3 @Binding var isPresented: Bool4 var onContinue: () -> Void5 6 var body: some View {7 VStack(spacing: 24) {8 Image(systemName: "chart.bar.xaxis")9 .font(.system(size: 60))10 .foregroundStyle(.blue)11 12 Text("Sana Daha İyi Deneyim Sunmak İstiyoruz")13 .font(.title2.bold())14 .multilineTextAlignment(.center)15 16 Text("Reklam performansını ölçmek için cihaz verisi kullanıyoruz. Bu sayede sana alakalı teklifler gösterebiliyoruz.")17 .foregroundStyle(.secondary)18 .multilineTextAlignment(.center)19 20 Button("Devam Et") {21 isPresented = false22 onContinue()23 }24 .buttonStyle(.borderedProminent)25 26 Button("Şimdi Değil") {27 isPresented = false28 // Tracking isteği yapma — kullanıcı red edecek29 AnalyticsManager.shared.configurePrivacyMode()30 }31 .foregroundStyle(.secondary)32 }33 .padding(32)34 }35}Ne zaman ATT istememeli?
- Uygulama ilk açıldığında (onboarding tamamlanmadan önce)
- Kullanıcı bir işlem yaparken (satın alma, kritik action)
- Push notification izni ile aynı anda (çoklu permission fatigue)
- Cold launch'da hemen
Ne zaman istenmeli?
- Onboarding tamamlandıktan sonra
- Kullanıcı uygulamanın değerini gördükten sonra (2-3. session)
- Belirli bir feature'a girerken (reklamlı içerik bölümü)
- Açıkça context sağlandıktan sonra
Consent Management Platforms
GDPR + CCPA + PDPL (Türkiye) + LGPD (Brezilya) gereklilikleri nedeniyle büyük uygulamalar Consent Management Platform (CMP) kullanıyor.
Popüler CMP'ler 2026:
Platform | iOS SDK | IAB TCF | Fiyat |
|---|---|---|---|
OneTrust | Evet | v2.2 | Kurumsal |
Usercentrics | Evet | v2.2 | €39/ay'dan |
Didomi | Evet | v2.2 | €99/ay'dan |
Apple native | Partial | Hayır | Ücretsiz |
swift
1// Usercentrics örneği (IAB TCF v2.2 uyumlu)2import Usercentrics3 4class ConsentManager {5 static func initialize() {6 UsercentricsCore.configure(7 options: UsercentricsOptions(settingsId: "YOUR_SETTINGS_ID")8 )9 }10 11 static func showConsentBanner(from viewController: UIViewController) async -> ConsentResult {12 return await withCheckedContinuation { continuation in13 let banner = UsercentricsBanner()14 banner.showFirstLayer(hostView: viewController) { userResponse in15 continuation.resume(returning: ConsentResult(16 analytics: userResponse.consents["ga4"]?.status ?? false,17 advertising: userResponse.consents["meta_pixel"]?.status ?? false18 ))19 }20 }21 }22}23 24struct ConsentResult {25 let analytics: Bool26 let advertising: Bool27}Önemli: CMP kullansan bile iOS-native ATT dialog'u şart. CMP, GDPR/CCPA consent'ini yönetir; ATT, iOS platform-level tracking kontrolü. İkisi birbirini tamamlar, biri diğerinin yerini almaz.
IDFA Alternatifleri 2026
ATT ile IDFA erişimi kısıtlandıktan bu yana industry attribution ve analytics için alternatifler geliştirdi.
1. SKAdNetwork (Apple's solution):
swift
1import StoreKit2 3// SKAdNetwork 4.0 — attribution without user identification4class AttributionManager {5 static func updateConversionValue(_ value: Int) {6 // 0-63 arası conversion value7 // Apple aggregated olarak advertiser'a iletir8 SKAdNetwork.updatePostbackConversionValue(9 value,10 coarseValue: .high, // SKAdNetwork 4.0 yeni11 lockWindow: false12 ) { error in13 if let error = error {14 print("SKAdNetwork error: \(error)")15 }16 }17 }18}19 20// Conversion value semantics — örnek mapping21// 0: install22// 1-10: engagement level23// 11-20: purchase tier24// 21-30: retention bucket2. Meta Advanced Matching:
swift
1// IDFA olmadan hashed user data ile matching2// E-posta/telefon SHA-256 hash ile gönderilir3MetaAdvancedMatchingManager.configure(4 email: "sha256_hash_of_email",5 phone: "sha256_hash_of_phone"6)7// Meta, kendi user database ile match eder3. AppsFlyer SKAN + Probabilistic:
swift
1// ATT kabul edenler için IDFA2// Reddedenlere probabilistic modeling (IP + device signals)3// IDFA erişimi yokken fingerprinting yasaklı — sadece SKAdNetwork4. Privacy-preserving analytics:
swift
1// Mixpanel Identity Merge — server-side, non-identifying2// PostHog — open source, self-hosted option3// Amplitude — cohort analytics without user-level tracking4 5// Genel yaklaşım: session-level, aggregate, no persistent ID6class PrivacyAnalytics {7 // Session ID: app open'da random UUID, kapanınca sil8 private let sessionID = UUID().uuidString9 10 func trackEvent(_ name: String, properties: [String: Any] = [:]) {11 var enrichedProps = properties12 enrichedProps["session_id"] = sessionID13 enrichedProps["app_version"] = Bundle.main.appVersion14 // User-specific ID yok — session bazlı aggregate15 sendToBackend(event: name, properties: enrichedProps)16 }17}2026 App Store Rejection Sebepleri
Gerçek App Review rejection deneyimlerinden derlenen 2026 güncel liste:
Privacy Manifest ile ilgili rejectionlar:
swift
1Rejection 1:2"ITMS-91053: Missing API declaration"3Sebep: NSUserDefaults API kullanıldı, manifest'te declare edilmedi4Çözüm: PrivacyInfo.xcprivacy'e CA92.1 reason ekle5 6Rejection 2:7"ITMS-91055: Invalid privacy manifest"8Sebep: NSPrivacyAccessedAPITypeReasons array boş bırakıldı9Çözüm: Geçerli reason kodu ekle(boş array kabul edilmiyor)10 11Rejection 3:12"ITMS-91056: Privacy manifest in dependency"13Sebep: Third-party SDK(örn. eskiFirebase sürümü) manifest içermiyor14Çözüm: SDK'yı güncelle veya App Review Notes'a açıklama ekle15 16Rejection 4:17"ITMS-91057: NSPrivacyTracking inconsistency"18Sebep: NSPrivacyTracking = false ama tracking domain'ler var19Çözüm: NSPrivacyTracking = true yap veya domain'leri kaldır20 21Rejection 5:22"5.1.1 Data Collection and Storage"23Sebep: Kullanıcı onayı olmadan kişisel veri toplandı24Çözüm: Consent flow ekle, privacy policy güncelleATT ile ilgili rejectionlar:
swift
1Rejection 6:2"5.1.2 Data Use and Sharing"3Sebep: ATT izni olmadan kullanıcı track ediliyor4Çözüm: ATTrackingManager.requestTrackingAuthorization() ekle5 6Rejection 7:7"2.5.4 Software Requirements"8Sebep: ATT dialog öncesi "izin ver" için baskı yapan custom UI9Çözüm: Pre-permission screen tarafsız olmalı — "izin ver" için teşvik YASAKÖnlem stratejisi:
swift
1// Pre-submission checklist2// 1. xcrun privacy-manifest verify — lokal kontrol3// 2. Xcode "Generate Privacy Report" — tüm dependency'ler4// 3. ATT flow test: denied + authorized + not determined5// 4. Tracking domain DNS check — hangi domain'ler gerçekten kullanılıyor?6// 5. Privacy Nutrition Label'ı App Store Connect'te manuel reviewCompliance Checklist
2026 App Store submission için tam compliance checklist:
PrivacyInfo.xcprivacy:
- Dosya var ve doğru target'a üye
- NSPrivacyTracking doğru set (true/false)
- NSPrivacyTrackingDomains — tracking = true ise dolu, false ise boş
- NSPrivacyAccessedAPITypes — kullanılan her Required Reason API declare edildi
- Her API için geçerli reason kodu var (boş array yok)
- NSPrivacyCollectedDataTypes — gerçek veri toplama ile eşleşiyor
SDK Dependency'leri:
- Tüm SPM/CocoaPods/XCFramework manifest'leri var
- `xcrun privacy-manifest verify` clean geçti
- Firebase, Analytics SDK'lar güncel sürümde
ATT Implementation:
- `ATTrackingManager.requestTrackingAuthorization()` implemente
- Info.plist'te `NSUserTrackingUsageDescription` var
- ATT öncesi pre-permission screen tarafsız (baskı yok)
- Denied durumunda graceful degradation çalışıyor
- Tracking domain'ler ATT denied'da engelleniyor (test edildi)
Privacy Policy:
- Privacy policy URL App Store Connect'te kayıtlı
- Toplanan veriler privacy policy ile eşleşiyor
- GDPR/CCPA/PDPL uyumlu bölümler var
App Store Connect:
- Privacy Nutrition Label dolduruldu
- "App Collects Data" beyanı gerçekle eşleşiyor
- Data linked to identity doğru işaretlendi
bash
1#!/bin/bash2# privacy-audit.sh — Her PR'da otomatik çalıştır3 4echo "Checking Privacy Manifests for all dependencies..."5 6# SPM cache'inden tüm PrivacyInfo.xcprivacy dosyalarını bul7MANIFESTS=$(find ~/Library/Developer/Xcode/DerivedData -name "PrivacyInfo.xcprivacy" 2>/dev/null)8PACKAGE_DIRS=$(find .build -name "*.xcprivacy" 2>/dev/null)9 10# Manifest olmayan framework'leri tespit et11find . -name "*.xcframework" -o -name "*.framework" | while read framework; do12 if [ ! -f "$framework/PrivacyInfo.xcprivacy" ]; then13 echo "WARNING: No privacy manifest in $framework"14 fi15done16 17echo "Run 'xcrun privacy-manifest verify' for detailed analysis"ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
swift
1class ATTTimingManager {2 private static let sessionCountKey = "att_session_count"3 private static let hasRequestedKey = "att_has_requested"4 5 static func shouldRequestTracking() -> Bool {6 guard !UserDefaults.standard.bool(forKey: hasRequestedKey) else {7 return false // Zaten soruldu8 }9 10 let count = UserDefaults.standard.integer(forKey: sessionCountKey)11 return count >= 2 // 3. session'dan itibaren sor12 }13 14 static func incrementSessionCount() {15 let current = UserDefaults.standard.integer(forKey: sessionCountKey)16 UserDefaults.standard.set(current + 1, forKey: sessionCountKey)17 }18 19 static func markAsRequested() {20 UserDefaults.standard.set(true, forKey: hasRequestedKey)21 }22}23 24// AppDelegate veya SceneDelegate'de:25func sceneDidBecomeActive(_ scene: UIScene) {26 ATTTimingManager.incrementSessionCount()27 28 if ATTTimingManager.shouldRequestTracking() {29 Task {30 await TrackingManager.shared.requestTrackingIfNeeded()31 ATTTimingManager.markAsRequested()32 }33 }34}Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
**iOS 19 Privacy Layer (Beta, 2026):** iOS 19 beta'da görülen yeni privacy özelliği — "Privacy Dashboard" ekranında kullanıcılar hangi app'in hangi API'yı ne zaman kullandığını görebilecek. Bu aşamada geliştirici için değişiklik gerektirmiyor ama şunu işaret ediyor: Privacy Manifest'teki her beyannamen kullanıcı tarafından görülebilir hale geliyor. Pratik öneri: Manifest'ini aggressive tut — sadece gerçekten kullandığın API'ları declare et. "Gelecekte lazım olabilir" diye ekstra reason declare etme. Her beyannamen audit trail oluşturuyor. **Fingerprinting detection (iOS 19 yeni):** iOS 19 ile Apple, bilinen fingerprinting pattern'lerini runtime'da tespit eden bir sistem sunuyor. `ct_syscall`, `getsockopt` ve benzeri low-level API kombinasyonları monitör ediliyor. Bu API'ları kullanan SDK'lar (eski sürüm bazı analytics SDK'lar) runtime'da kısıtlama alabilir — manifest'e ne yazarsan yaz. Fingerprinting şüphesi taşıyan API kombinasyonları: - `mach_absolute_time()` + `sysctlbyname("hw.machine")` + `UIDevice.model` - `UIScreen.main.scale` + `ProcessInfo.systemUptime` + disk info Bu kombinasyonları kullanan third-party library kullanıyorsan şimdi güncelle veya çıkar.
Sonuç
iOS Privacy Manifests, sadece compliance checkbox doldurmak değil — kullanıcıya ve App Store review ekibine şeffaf bir sözleşme sunmak. 2026'da bu sözleşmenin detayları her zamankinden daha fazla denetleniyor: binary analizi, SDK manifest kontrolü, ATT flow review.
Doğru yaklaşım: Privacy-by-design. Baştan toplanacak veriyi minimize et, her toplanan veri için açık reason belirle, ATT flow'unu kullanıcı deneyimine zarar vermeden uygula. Bu yaklaşım hem App Store rejection'ı önler hem de kullanıcı güvenini artırır — ve araştırmalar güvenilir bulunan uygulamaların retention'ının %23 daha yüksek olduğunu gösteriyor.
İlgili Kaynaklar:
- Apple Developer — Privacy Manifests
- Apple Developer — Required Reason API
- Apple Developer — App Tracking Transparency
- Apple WWDC 2023 — Privacy Manifests
- App Store Review Guidelines 5.1
Sonraki adım: StoreKit 2 Production Subscription Guide ve iOS Privacy Compliance ATT yazılarını incele.
