SwiftUI eğitimi kapsamında PrivacyInfo.xcprivacy dosyasını, Required Reason API bildirimlerini ve CI denetimini kurun. App Store yayınlama öncesinde bağımlılık kaynaklı gizlilik hatalarını sürüm artefaktında yakalayın.
SwiftUI Eğitiminde Privacy Manifest ve Required Reason API Denetimi
SwiftUI eğitimi: Privacy Manifest neden kaynak koddan değil artefakttan denetlenmeli?
Privacy manifest, uygulamanın topladığı veri türlerini ve Required Reason API kullanımlarını beyan eden PrivacyInfo.xcprivacy dosyasıdır. Ancak Swift Package Manager ile gelen bir XCFramework, statik olarak linklenen bir SDK veya build phase ile kopyalanan bir bundle kendi manifestini taşıyabilir. Bu nedenle yalnızca ana target altındaki manifesti incelemek yetersizdir. App Store yayınlama kontrolü, arşivden çıkan uygulama paketindeki toplam beyana ve tespit edilen API kullanımına bakar; Debug derlemesinin dosya ağacı bu gerçeği temsil etmez.
Önce Release arşivini üretin ve manifestlerin gerçekten pakete girdiğini doğrulayın. CI ajanında aşağıdaki komut, uygulama ve gömülü framework bundle'larındaki tüm manifestleri listeler. find sonucunda ana uygulama dışında beklemediğiniz bir SDK manifesti görürseniz, SDK'nın hangi API kategorilerini beyan ettiğini ayrıca inceleyin.
xcodebuild archive -workspace Acme.xcworkspace -scheme Acme -configuration Release -archivePath "$PWD/build/Acme.xcarchive" CODE_SIGNING_ALLOWED=NO
find build/Acme.xcarchive/Products/Applications -name PrivacyInfo.xcprivacy -printBu kontrol özellikle iphone uygulama geliştirme ekiplerinde önemlidir: uygulama kodunuz UserDefaults çağırmasa bile analitik, A/B test veya hata raporlama SDK'sı bu API'ye erişebilir. Tersine, SDK dokümantasyonunda manifest yazıyor olması da yeterli değildir; kullandığınız paket sürümünün arşive gerçekten manifest kopyaladığını ölçmelisiniz. Arşiv tabanlı denetim bu iki farklı durumu ayırır.
Xcode eğitimi: Required Reason API beyanını çağrı amacına bağlamak
Required Reason API kategorilerinde kritik nokta, API adına göre rastgele reason code eklememektir. Örneğin UserDefaults erişiminin nedeni, uygulamanın kullanıcı tercihlerini saklamak olabilir; ama aynı depoyu cihazlar arası izleme için kullanmak beyan satırı eklenerek meşrulaşmaz. Apple'ın güncel dokümantasyonundaki kategori ve reason code eşleşmesini, çağrının bulunduğu dosya ve ürün gereksinimi ile birlikte bir envantere yazın.
Aşağıdaki örnek, uygulama işlevi için kullanıcı tercihlerini saklayan bir kullanımın manifest karşılığını gösterir. CA92.1 yalnızca bu amaca uyuyorsa kullanılmalıdır; kopyala-yapıştır bir varsayılan değildir. Proje navigator'unda uygulama target'ına eklenen dosyanın Target Membership kutusunun işaretli olduğundan emin olun. Aksi halde dosya repoda bulunur fakat arşive girmez.
<?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>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>Xcode'da plist editörü yalnızca XML'in biçimsel olarak geçerli olmasını kolaylaştırır; reason kodunun ürün davranışıyla semantik uyumunu doğrulamaz. Bu yüzden her manifest satırına issue takip sistemindeki karar kaydını ekleyin: API kategorisi, çağrıyı yapan modül, veri akışı, seçilen reason ve inceleyen kişi. Bu kayıt, SDK güncellemesinde neden bir satırın kaldırılabildiğini veya korunması gerektiğini açıklar.
iOS MVVM mimarisi ile gizlilik erişimlerini izlenebilir sınırlara taşımak
ios mvvm mimarisi içinde ViewModel'in doğrudan UserDefaults.standard, disk kapasitesi veya dosya zaman damgası okuması yapması, Required Reason API envanterini dağınık hale getirir. Erişimi küçük bir altyapı protokolünde toplayın ve ViewModel'e enjekte edin. Böylece manifestteki her kategori için kod tabanında aranabilir tekil sahiplik oluşur; testte de gerçek sistem deposu yerine bellek içi fake kullanılır.
protocol PreferenceStore: Sendable {
func bool(forKey key: String) -> Bool
func set(_ value: Bool, forKey key: String)
}
final class AppPreferenceStore: PreferenceStore, @unchecked Sendable {
func bool(forKey key: String) -> Bool {
UserDefaults.standard.bool(forKey: key)
}
func set(_ value: Bool, forKey key: String) {
UserDefaults.standard.set(value, forKey: key)
}
}
@MainActor
final class SettingsViewModel: ObservableObject {
@Published private(set) var analyticsEnabled = false
private let preferences: PreferenceStore
init(preferences: PreferenceStore) {
self.preferences = preferences
analyticsEnabled = preferences.bool(forKey: "analytics.enabled")
}
func setAnalyticsEnabled(_ enabled: Bool) {
preferences.set(enabled, forKey: "analytics.enabled")
analyticsEnabled = enabled
}
}Buradaki incelik @unchecked Sendable satırıdır: bu işaret, sınıfın thread-safe olduğunu derleyiciye kanıtlamaz. Store'u actor sınırları arasında gerçekten paylaşacaksanız, erişimi bir actor ile seri hale getirin veya @MainActor ile sınırlandırın. Aksi halde gizlilik denetimi için yapılan soyutlama, eşzamanlı erişimde veri yarışı gizleyebilir. swift eğitimi veya swift kursu içinde bu ayrım genellikle yalnızca dependency injection olarak anlatılır; üretimde sahiplik ve izolasyon kararını beraber vermek gerekir.
Bu sınırlama ayrıca bağımlılık denetimini hızlandırır. Örneğin rg -n "UserDefaults|attributesOfItem|systemUptime|volumeAvailableCapacity" Sources komutunu CI'da rapor olarak çalıştırın. Yeni bir sonuç çıktığında geliştirici ya mevcut altyapı katmanına yönelir ya da yeni manifest kategorisi ve karar kaydı ekler. Bu arama binary içindeki çağrıları göremez; üçüncü taraf SDK'lar için arşiv taraması zorunlu kalır.
iOS eğitimi ve app store yayınlama için CI gizlilik kapısı
Manifestin varlığını kontrol etmek tek başına yeterli değildir; bozuk plist, boş reason dizisi veya yanlış category değeri ancak paket incelemesinde görünür hale gelebilir. Aşağıdaki Python denetimi, Release archive altındaki her manifesti plistlib ile parse eder ve Required Reason API girdilerinde boş reason listesini build hatasına dönüştürür. Bunu archive adımından hemen sonra, export veya upload adımından önce çalıştırın.
python3 - <<'PY'
from pathlib import Path
import plistlib
import sys
root = Path("build/Acme.xcarchive/Products/Applications")
failed = False
for path in root.rglob("PrivacyInfo.xcprivacy"):
try:
with path.open("rb") as f:
manifest = plistlib.load(f)
for item in manifest.get("NSPrivacyAccessedAPITypes", []):
category = item.get("NSPrivacyAccessedAPIType", "")
reasons = item.get("NSPrivacyAccessedAPITypeReasons", [])
if not category or not isinstance(reasons, list) or not reasons:
print(f"Invalid required-reason declaration: {path}: {item}")
failed = True
except Exception as error:
print(f"Unreadable manifest: {path}: {error}")
failed = True
if failed:
sys.exit(1)
PYDaha sağlam bir kapı için izin verilen kategori-reason çiftlerini repoda sürümlenen bir JSON dosyasında tutun ve scriptin her manifest girdisini bu allowlist ile karşılaştırmasını sağlayın. Böylece bir geliştirici, sadece doğrulamanın geçmesi için geçerli ama ürünle ilgisiz bir reason ekleyemez. Dependabot veya benzeri bir bağımlılık güncelleme PR'ında manifest diff'ini zorunlu inceleme çıktısı yapın.
ios kursu veya xcode eğitimi materyallerinde sık görülen hata, simulator üzerinde çalıştığı için teslim sürecinin tamamlandığını varsaymaktır. Gizlilik beyanı için kabul kriteri farklıdır: Release archive'da manifest bulunmalı, plist parse edilmeli, API-reason envanteri ürün davranışıyla eşleşmeli ve bağımlılık güncellemesinde bu sonuç yeniden üretilmelidir. Bu dört kontrol, yerel IDE durumundan bağımsız, denetlenebilir bir teslim kanıtı üretir.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Sık Sorulan Sorular
SwiftUI eğitimi sırasında PrivacyInfo.xcprivacy dosyasını hangi target'a eklemeliyim?
Uygulamanın kendi Required Reason API çağrıları için dosyayı app target'ına ekleyin ve Release archive içinde bulunduğunu find komutuyla doğrulayın. Uygulama extension'ı API'yi kendi başına çağırıyorsa extension target'ını ayrıca inceleyin. Dosyanın Project Navigator'da görünmesi yeterli değildir; Target Membership ve arşiv çıktısı kontrol edilmelidir.
iOS MVVM mimarisi Privacy Manifest ihtiyacını ortadan kaldırır mı?
Hayır. MVVM sadece erişimin sahipliğini netleştirebilir. AppPreferenceStore gibi tek bir katmanda UserDefaults çağrısı toplansa bile, bu çağrı ürün davranışında varsa uygun kategori ve reason code manifestte kalmalıdır. Kazanç, rg ile çağrı sahibini bulabilmek ve fake store ile testte gerçek API kullanımını ayırabilmektir.
app store yayınlama öncesinde üçüncü taraf SDK manifestlerini nasıl kontrol ederim?
Release .xcarchive üretin, Products/Applications altında PrivacyInfo.xcprivacy dosyalarını recursive olarak listeleyin ve her dosyayı plistlib veya plutil ile parse edin. Sadece kaynak paketini incelemeyin: XCFramework içeriği, build phase ve paketleme ayarları manifestin son uygulama bundle'ına girip girmediğini değiştirebilir.
swift kursu projesinde UserDefaults için herhangi bir reason code seçmek yeterli mi?
Yeterli değildir. Kodun gerçek kullanım amacını belirleyin, ardından Apple dokümantasyonunda o amaca izin verilen reason code'u seçin. Örneğin tercih saklama ile takip kimliği oluşturma aynı teknik depoyu kullansa bile aynı ürün gerekçesi değildir. Seçimi API kategorisi, kaynak modül ve issue kaydıyla birlikte gözden geçirin.
AI / LLM Discovery
Bu makale Opendart Akademi iOS / Swift eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.


