Der Lebenszyklus der Einwilligung: Was nach der Altersprüfung ausgeliefert wird
Am 4. November 2025 hat Apple den App Store Server Notifications einen Benachrichtigungstyp hinzugefügt, der nicht bei einer Zahlung auslöst, sondern bei einer Entscheidung der Eltern: RESCIND_CONSENT, der anzeigt, dass „die Eltern oder Erziehungsberechtigten ihre Einwilligung in die App-Nutzung durch ein Kind widerrufen haben“.12
Er ist der einzige der 23 Typen dieses Dienstes, dessen Payload statt Transaktionsinformationen ein appData-Objekt trägt, und appData enthält eine signierte App-Transaktion, die existiert, „selbst wenn ein Kunde keine In-App-Käufe tätigt“.319 Eine App, die noch nie etwas verkauft hat, bekommt damit ihren ersten Grund, einen Endpunkt für Benachrichtigungen zu betreiben.
Die Social-Media-Angabe behandelt das Auslesen der Altersspanne einer Person: das Entitlement, die Schranken und die Bedeutung der zurückgegebenen Grenzen. Betrachten Sie das als geklärt und setzen Sie einen Schritt später an. Die Altersprüfung beantwortet, wie alt jemand ist. Die drei APIs hier beantworten, wer zustimmt, ob eine bereits erteilte Zustimmung eine Änderung an Ihrer App überdauert und was geschieht, wenn ein Erziehungsberechtigter sie zurücknimmt.21012
TL;DR
- Drei APIs sind der Altersprüfung nachgelagert, und Apple liefert sie als Satz aus: die Significant Change API unter PermissionKit,
AppStore.ageRatingCodein StoreKit und die Server-BenachrichtigungRESCIND_CONSENT.45 - Apple knüpft seine Liste der vier Werkzeuge an Texas, Utah und Louisiana, nicht allein an Texas; jedes Datum, das Apple für diese drei genannt hat, ist verstrichen, und Apple begrenzt die Pflicht auf „bestimmte Regionen, in denen es gesetzlich vorgeschrieben ist“.5815
- Die Schwelle, die darüber entscheidet, ob Sie überhaupt etwas davon ausführen, heißt
AgeRangeService.requiredRegulatoryFeatures, ist neu in 26.4 – und der Ablauf, den sie absichert, kostet iOS 26.5, wenn Sie ihn vollständig schreiben wollen.736 - Apple weigert sich, eine wesentliche Änderung zu definieren, sagt das viermal und verweist Sie an Ihre Rechtsberatung. Das einzige konkrete Beispiel, das Apple veröffentlicht, schreibt es dem Gesetz zu: Apple schreibt, das texanische Recht werte eine Änderung der Alterseinstufung Ihrer App als solche.48
- Ihre Einstufung kann sich ohne einen Build von Ihnen ändern. Am 18. Juni 2026 hat Apple die australische Stufe 15+ abgeschafft und Vietnam ein neues vierstufiges Schema gegeben – beides, ohne von irgendeinem Entwickler eine Einreichung zu verlangen.937
- Der Widerruf ist der Zweig, den niemand baut, und Apples Dokumentation baut ihn kaum besser:
RESCIND_CONSENTtaucht in keiner der Lebenszyklus-Tabellen auf der Seite auf, die ein Server-Team liest.2
Erteilen, erneut erteilen, widerrufen. Die ersten beiden Wege dokumentiert Apple mit einem Beispielprojekt und einer Testmatrix für die Sandbox. Der dritte bekommt einen Enum-Wert und vier Felder – ungefähr die Aufmerksamkeit, die er, wie sich herausstellte, auch in meinem eigenen Code bekommt.
Der Kalender, den Apple viermal veröffentlicht hat
Jedes Datum unten stammt aus Apples eigenen Developer News, und die Abfolge zählt mehr als jeder einzelne Eintrag.
Angekündigt hat Apple das texanische SB2420 am 8. Oktober 2025, datiert auf „Beginnend am 1. Januar 2026“, und dabei die eigene Reaktion beschrieben statt des Gesetzestextes: Neue Apple-Accounts für Benutzer unter 18 sollten einer Familienfreigabe-Gruppe beitreten, und „Eltern oder Erziehungsberechtigte müssen für sämtliche App-Store-Downloads, App-Käufe und Transaktionen des Minderjährigen über Apples In-App-Kaufsystem ihre Einwilligung erteilen“.13 Am 4. November hat Apple die Werkzeuge benannt und in den 26.2-Betas ausgeliefert.4 Am 23. Dezember kam der Plan zum Stillstand: „Eine kürzlich von einem Bezirksgericht erlassene einstweilige Verfügung hat die Durchsetzung des texanischen Gesetzes SB2420 ausgesetzt … Apple wird die zuvor angekündigten Umsetzungspläne pausieren.“14 Am 3. Juni 2026 ging es wieder los: „Aufgrund einer kürzlich ergangenen Gerichtsentscheidung, die eine einstweilige Verfügung gegen das texanische Gesetz SB 2420 aufhebt … Diese Änderungen treten ab dem 4. Juni 2026 in Kraft.“5
Acht Monate Schleudertrauma an einem einzigen Gesetz – und die APIs haben sich kein einziges Mal bewegt. Sie kamen mit 26.2, blieben während der gesamten einstweiligen Verfügung für Tests in der Sandbox verfügbar und standen bereit, als sie aufgehoben wurde.14 Wer die Pause im Dezember als Erlaubnis zum Aufschieben gelesen hat, hat fünf Monate Vorlauf verloren.
Der Rest der Landkarte kam am 24. Februar 2026 und reicht über Texas hinaus.
| Rechtsraum | Von Apple genanntes Datum | Was laut Apple gilt |
|---|---|---|
| Australien, Brasilien, Singapur | 24. Februar 2026 | Apple blockiert Downloads von Apps mit der Einstufung 18+, „sofern nicht durch angemessene Methoden bestätigt wurde, dass es sich um Erwachsene handelt“15 |
| Utah | 6. Mai 2026 | Alterskategorien werden für neue Apple-Accounts auf Anfrage geteilt15 |
| Texas | 4. Juni 2026 | Neue Apple-Accounts „unterliegen jetzt dem Gesetz“: Einwilligung für Downloads, In-App-Käufe und wesentliche Änderungen im Namen Minderjähriger unter 18, und Erziehungsberechtigte können widerrufen5 |
| Louisiana | 1. Juli 2026 | Alterskategorien werden für neue Apple-Accounts auf Anfrage geteilt15 |
Texas ist der Ausreißer bei der Schwelle, nicht bei den Werkzeugen. Apple beschreibt Texas als Einwilligung „im Namen Minderjähriger unter 18 Jahren“ und veröffentlicht die Kategorien als „unter 13, 13–15, 16–17 oder über 18“ – genau das, was die API erzeugt: „Sie können bis zu drei Altersschwellen angeben, die bis zu vier mögliche Altersspannen ergeben.“4529 Für Utah und Louisiana nennt Apple das Teilen der Alterskategorie auf Anfrage und erklärt dann, alle vier Werkzeuge seien „erweitert worden, um Entwickler bei der Erfüllung der Compliance-Pflichten für Louisiana und Utah zu unterstützen“ – die Significant Change API ausdrücklich darunter.15 Die Werkzeuge gelten also nicht nur für Texas. Ob die Pflichten es tun, sagt Apple nicht: Der Konzern begrenzt sie auf „bestimmte Regionen, in denen es gesetzlich vorgeschrieben ist“, und schickt die Frage stattdessen an Ihre Rechtsberatung.8
Lesen Sie die Tabelle nicht als Aussage über die Rechtslage und nicht als Compliance-Bewertung. Sie hält fest, was Apple angekündigt hat und welches Datum Apple daran geheftet hat. Ich bin Ingenieur, kein Jurist, und alles Folgende endet dort, wo die API endet.
Das Q&A, das Compliance-Fragen an Juristen weiterreicht, hat für die Release-Planung eine bessere Nachricht: Gefragt, ob irgendetwas davon die Prüfung ändert, antwortet Apple: „Nein, am App-Review-Prozess ändert sich nichts.“8 Die Pflichten greifen zur Laufzeit in den genannten Rechtsräumen, nicht bei der Einreichung.
Die Trennung ist damit sauber. Ob Ihre App in Texas, Utah oder Louisiana eine Einwilligung schuldet, ist eine Frage für eine dort zugelassene Anwältin oder einen dort zugelassenen Anwalt. Gegen welches SDK Sie bauen, ist es nicht: Apple erklärt, Sie „müssen Ihre App gegen die SDKs von iOS 26.2 und iPadOS 26.2 oder neuer mit Xcode 26.2 (17C52) oder neuer bauen“, um die Frameworks überhaupt zu erreichen, und bestehende Accounts unter iOS 18 oder älter „sind nicht betroffen“.8
Apple sagt Ihnen nicht, was „wesentlich“ bedeutet
Die Definitionslücke sitzt mitten in der Funktion, und vier Apple-Quellen reichen sie zurück, statt sie zu füllen: die Symbolseite („Sie bestimmen anhand der geltenden Vorschriften, was ein wesentliches Update darstellt“),12 beide Newsbeiträge („es liegt in der Verantwortung des Entwicklers zu bestimmen, wann eine wesentliche Änderung an seiner App vorliegt“),45 und das Q&A, direkt gefragt, ob eine Änderung der Nutzungsbedingungen oder des Datenschutzes zählt („Das kommt darauf an. Sie bestimmen anhand der geltenden Gesetze, was ein wesentliches App-Update darstellt“).8
Genau ein ausgearbeitetes Beispiel liefert Apple, und es stammt aus dem Gesetz statt von Apple: „Das texanische Recht betrachtet eine Änderung der Alterseinstufung einer App als wesentliche Änderung, und Entwickler sollten ihre Angaben zur Alterseinstufung in App Store Connect aktuell halten.“4
Was Apple sehr wohl definiert, ist der Text, den Sie schreiben. SignificantAppUpdateTopic führt ein gutes und ein schlechtes Beispiel nebeneinander auf – für eine Symbolseite ungewöhnlich offenherzig:
// Specific
let topic = SignificantAppUpdateTopic(
description: "This update adds video calling and location sharing features."
)
// Vague
let topic = SignificantAppUpdateTopic(
description: "We've made improvements to the app."
)
Apples Anweisung rund um dieses Codebeispiel ist unmissverständlich: „Verwenden Sie eine knappe, verständliche Sprache, die klar erklärt, was sich in Ihrer App geändert hat. Eltern und Erziehungsberechtigte sehen diese Beschreibung, wenn sie über die Erteilung der Erlaubnis entscheiden.“12 Floskeln aus den Versionshinweisen landen damit vor einem Elternteil, das darüber entscheidet, ob sein Kind den Zugang behält – und werden so zum folgenreichsten Changelog-Text, den die meisten Apps je ausliefern.
Die Pflicht, die an der Antwort hängt, ist überhaupt nicht vage, auch wenn Apple sich um deren Auslöser herumdrückt. Apple macht Sie „dafür verantwortlich, den Zugang zu Ihrer App oder zu einzelnen Funktionen zu verhindern, wo dies erforderlich ist“, und stellt dann nüchtern fest: „Bis die Eltern ihre Einwilligung erteilen, muss dem Kind der Zugang zum wesentlichen Update verwehrt bleiben, was sämtliche App- und Accountdaten oder einzelne Funktionen umfassen kann.“8 Die Wendung „sämtliche App- und Accountdaten“ leistet dort eine Menge Arbeit. Apple überlässt Ihnen den Wirkungsradius und nennt den gesamten Account als Obergrenze.
Der Zustandsautomat – und wo Apples eigenes Beispiel leckt
Apple hat ein Beispielprojekt veröffentlicht, „Implementing age assurance and permissions“, die einzige durchgängige Beschreibung des Ablaufs.6 Liest man es als Zustandsautomat, treten vier Zweige zutage und ein Codebeispiel, das man umschreiben sollte.
Der erste Zweig ist der billige. AgeRangeService.requiredRegulatoryFeatures liefert Set<AgeRangeService.RegulatoryFeature> mit drei Mitgliedern: declaredAgeRangeRequired, significantAppChangeRequiresParentalConsent und significantAppChangeRequiresAdultNotification.7 Apples Beispiel fragt das zuerst ab, und „ist keine der beiden Funktionen vorhanden, überspringt die App den Ablauf vollständig“.6 Apple beschreibt die Eigenschaft als Abbild von „Region und Accounteinstellungen“ einer Person, was ich als Zusage lese, dass Benutzer außerhalb der genannten Rechtsräume mit leeren Händen zurückkommen – garantiert ist davon bei Apple nichts.7
Die übrigen Zweige teilen sich nach Alter und danach, wie das Alter festgestellt wurde:
| Person | Erforderliche regulatorische Funktion | Was Apples Beispiel tut |
|---|---|---|
| Minderjährig | significantAppChangeRequiresParentalConsent |
Sendet eine PermissionQuestion an die Erziehungsberechtigten6 |
| Erwachsen, bestätigte Methode | significantAppChangeRequiresAdultNotification |
Zeigt das Bestätigungs-Sheet des Systems6 |
| Erwachsen, keine bestätigte Methode | eine von beiden | Sperrt den Zugang, „bis die Person ihren Account in den Einstellungen verifiziert“6 |
| Teilen abgelehnt | eine von beiden | Wertet den Fall aus, zeigt dann aber keinen Zweig dafür6 |
Bei der dritten Zeile lohnt es sich zu verweilen. Eine erwachsene Person, die ihrem Apple-Account nie eine Zahlungsmethode hinzugefügt hat, wird von Apples Referenzimplementierung ausgesperrt – in einem Ablauf, der Kinder schützen soll. Apple bietet dafür weder einen alternativen Zweig noch eine Möglichkeit, das zu übergehen.
Gegen die veröffentlichten Deklarationen zusammengesetzt, sieht die Verzweigung so aus. Die Aufteilung zwischen Erwachsenen und Minderjährigen folgt Apples Beispiel plus der Testmatrix für die Sandbox, in der ein Account ab 18 einen lowerBound von 18 ohne obere Grenze und eine ageRangeDeclaration von confirmed oder selfDeclared zurückgibt. Beachten Sie die Verfügbarkeitsuntergrenze: .confirmed auszulesen kostet Sie iOS 26.5, ein Release später als alles andere in diesem Ablauf.61136
import DeclaredAgeRange
import PermissionKit
import SwiftUI
@available(iOS 26.5, *)
struct SignificantChangeGate: View {
enum Phase {
case checking
case clear
case awaitingGuardian(PermissionQuestion<SignificantAppUpdateTopic>)
case blocked
}
let changeDescription: String
@Environment(\.requestAgeRange) private var requestAgeRange
@Environment(\.showSignificantUpdateAcknowledgment) private var acknowledge
@State private var phase: Phase = .checking
var body: some View {
switch phase {
case .checking:
ProgressView().task { await resolve() }
case .clear:
ChangedFeatureView()
case .awaitingGuardian(let question):
PermissionButton(question: question) { Text("Ask a parent to approve") }
case .blocked:
AccountVerificationPrompt()
}
}
private func resolve() async {
let features = (try? await AgeRangeService.shared.requiredRegulatoryFeatures) ?? []
guard !features.isEmpty else {
phase = .clear // nothing applies to this person
return
}
guard let response = try? await requestAgeRange(ageGates: 18),
case let .sharing(range) = response else {
phase = .blocked // declined or unavailable: Apple documents no branch
return
}
let isAdult = range.lowerBound == 18
let isConfirmed = range.ageRangeDeclaration == .confirmed
switch (isAdult, isConfirmed) {
case (true, true) where features.contains(.significantAppChangeRequiresAdultNotification):
try? await acknowledge(updateDescription: changeDescription)
phase = .clear
case (true, false):
phase = .blocked // adult with no confirmed method
case (true, true):
phase = .clear
case (false, _):
guard features.contains(.significantAppChangeRequiresParentalConsent) else {
phase = .clear
return
}
let topic = SignificantAppUpdateTopic(description: changeDescription)
phase = .awaitingGuardian(PermissionQuestion(significantAppUpdateTopic: topic))
}
}
}
Die Frage zu senden ist die leichte Hälfte. Beim Empfang der Antwort leckt Apples Beispiel, und das Codebeispiel ist kurz genug, um es genau zu lesen:6
for await response in AskCenter.shared.responses(for: SignificantAppUpdateTopic.self) {
guard response.choice.answer == .approval else {
return
}
versionManager.handleAllChanges()
}
Ein return innerhalb von for await verlässt die Sequenz. Eine einzige Ablehnung, und die App beobachtet dieses Thema bis zum nächsten Start nicht mehr – ein Erziehungsberechtigter, der auf „Ablehnen“ tippt und es sich eine Minute später anders überlegt, schickt seine Zustimmung in einen Strom, den niemand liest. Schreiben Sie stattdessen continue und protokollieren Sie die Ablehnung. Dass ich das Codebeispiel als Fehler lese und nicht als Absicht, ist meine Schlussfolgerung; die Korrektur kostet so oder so ein Schlüsselwort. Entwerfen Sie den Listener so, als gäbe es keinen Start im Hintergrund: Versprochen hat ihn nur die abgekündigte Sequenz, die er ersetzt hat.2021
„Ausstehend“ ist ein Zustand – und hat kein Timeout, das Sie steuern
In der Mitte des Lebenszyklus steckt die eigentliche Entwurfsarbeit, geprägt von fünf dokumentierten Verhaltensweisen. Beginnen wir mit der, die Apple nur halb beantwortet: PermissionQuestion.expirationDate ist ein Optional<Date>, nach dessen Ablauf „die Person, welche die Frage erhält, nicht mehr antworten kann“ – einen Standardwert dafür veröffentlicht Apple nicht.16
Ein Kind kann abbrechen, bevor die Erziehungsberechtigten die Frage überhaupt zu sehen bekommen: „Zu jedem Zeitpunkt im Ablauf der Sendeanfrage hat das Kind die Möglichkeit, die Anfrage abzubrechen … In diesem Fall stellt das System der aufrufenden App für diese Frage keine Antwort zu.“17 Keine Antwort, kein Fehler, kein Callback. Ihr ausstehender Zustand bleibt ewig ausstehend, wenn Sie ihn nicht selbst mit einem Timeout versehen.
Eine erwachsene Person zu fragen, wirft einen Fehler. Der Sandbox-Artikel dokumentiert einen Fall, den die Symbolseite leer lässt: „Der Aufruf von AskCenter.ask(_:) für einen erwachsenen Benutzer wirft diesen Fehler, weil er die Voraussetzungen für elterliche Erlaubnisanfragen nicht erfüllt.“11 AskError.notAvailable ist einer von zwei Fällen des Enums ohne eigene Kurzbeschreibung auf seiner Seite – und derjenige, den Erwachsene auslösen.18 Verzweigen Sie nach Alter, bevor Sie fragen, statt den geworfenen Fehler abzufangen.
Der Zustimmungsstatus gehört in iCloud, nicht in den App-Container. Apples Beispiel schreibt jede bestätigte Änderung in NSUbiquitousKeyValueStore und beobachtet didChangeExternallyNotification, „damit andere Geräte denselben Ablauf nicht erneut zeigen“.6 Ein Elternteil, das auf dem iPhone zustimmt, sollte auf dem iPad keine zweite Anfrage erzeugen – und PermissionKit nimmt Ihnen davon nichts ab.
Das beste Detail des Beispiels löst ein Problem, das die meisten Teams falsch ausliefern würden. Neuinstallationen sollen keiner Änderung zustimmen, die sie nie erlebt haben; also liest Apple AppTransaction.originalAppVersion und „markiert alle Änderungen, die die App mit dieser Version oder davor eingeführt hat, automatisch als erledigt“.619 Die Nachverfolgung der Einwilligung läuft damit pro Änderung und pro Person: Änderungskennungen samt Einführungsversion, kein boolescher Wert.
Ihre Alterseinstufung kann sich ohne Build ändern
AppStore.ageRatingCode ist eine static var, die asynchron ein Int? liefert, verfügbar ab 26.2 unter iOS, iPadOS, macOS, tvOS, visionOS und watchOS.10 Apple nennt als Zweck den Vergleich, nicht die Deutung: „Verwenden Sie diese Eigenschaft, um die Alterseinstufung Ihrer App abzurufen und mit der zuletzt bekannten Einstufung zu vergleichen, um zu prüfen, ob sie sich geändert hat.“10 Mehr als ein Vergleich ist nicht zu holen, denn eine Zuordnung von Ganzzahl zu Einstufungsstufe veröffentlicht Apple nirgends in der Dokumentation. Sie können nicht fragen, ob Sie 13+ sind, sondern nur, ob Sie noch das sind, was Sie beim letzten Mal waren – der eigentliche Vertrag lautet also: Sie speichern den vorherigen Wert und verantworten den ersten Durchlauf.
Warum eine App ihre eigene Einstufung überwachen sollte, wird klar, sobald man bemerkt, dass Einstufungen sich ohne Release bewegen. Am 21. Mai 2026 hat Apple angekündigt, ab dem 18. Juni werde „die Alterseinstufung 15+ im App Store in Australien nicht mehr verfügbar“ sein, und Vietnam ein regionsspezifisches vierstufiges Schema gegeben, abgeleitet aus vorhandenen Fragebogenantworten.9 Beides ist eingetreten: Die Australien-Tabelle in der Hilfe zu App Store Connect führt inzwischen 16+ und R 18+ ohne eine Zeile für 15+, und Vietnam hat eine eigene Tabelle.37 Keine der beiden Änderungen verlangte eine Einreichung, einen Build oder irgendeine Handlung des Entwicklers – und Apple schreibt, das texanische Recht werte eine geänderte Einstufung als wesentliche Änderung.4
Vergleichen Sie das mit einer Änderung, die Sie selbst anstoßen: „Aktualisiert ein Entwickler die Alterseinstufung seiner App, wird die Einstufung auf allen Benutzergeräten aktualisiert, sobald die Version live ist.“4 Ihre eigenen Änderungen reisen mit einem Release, das Sie instrumentieren können. Apples Änderungen nicht – und genau diese Lücke füllt die Eigenschaft.
Das Testproblem ist mehr als eine Lücke. Eine Antwort von Apple Staff in den Developer Forums sagt es direkt: „Ein Wert von 0 ist während der Entwicklung Ihrer App zu erwarten, wenn sie aus Xcode und in Sandbox-Umgebungen (einschließlich TestFlight) gebaut und ausgeführt wird.“22 Null ist nicht nil, also passiert Apples eigenes dokumentiertes Beispiel sein guard let und reicht 0 als gültige Einstufung weiter – genau das, was der Entwickler, der jenen Thread eröffnet hat, auf einem echten Gerät gesehen hat.1022
Denken Sie das zu Ende. Speichern Sie 0 als Ausgangswert, dann liest der erste Start aus dem App Store einen echten Code, sieht eine Änderung und bittet ein Elternteil, erneut in nichts einzuwilligen. Dass man 0 als Sentinel behandelt, den man nie in den Ausgangswert schreibt, ist meine Schlussfolgerung aus Apples beiden Aussagen – und die eine Zeile defensiven Codes, ohne die ich nicht ausliefern würde.
Apples Verfügbarkeits-Metadaten tragen einen weiteren Befund, den keine Prosaseite ausspricht. Die Plattformzeilen dieser vier Fähigkeiten lassen an unterschiedlichen Stellen Löcher:
| Fähigkeit | iOS / iPadOS | macOS | Mac Catalyst | visionOS | tvOS / watchOS |
|---|---|---|---|---|---|
AppStore.ageRatingCode10 |
26.2 | 26.2 | keine Zeile | 26.2 | 26.2 |
requiredRegulatoryFeatures7 |
26.4 | 26.4 | 26.4 | keine Zeile | keine Zeile |
SignificantAppUpdateTopic, PermissionButton1226 |
26.2 | 26.2 | 26.2 | 26.2 | keine Zeile |
showSignificantUpdateAcknowledgment27 |
26.4 | keine Zeile | 26.4 | keine Zeile | keine Zeile |
Zwei Asymmetrien fallen heraus. Eine native macOS-App kann erfahren, dass significantAppChangeRequiresAdultNotification für eine Person gilt, und hat keine API, um dem nachzukommen: showSignificantUpdateAcknowledgment(in:updateDescription:) nimmt eine UIWindowScene entgegen und führt keine macOS-Zeile, und die SwiftUI-Variante SignificantUpdateAction endet bei denselben drei Plattformen.27 Für den benachbarten Aufruf requestAgeRange hat Apple durchaus eine NSWindow-Variante geliefert, weshalb sich die Auslassung eher als Lücke denn als Entscheidung liest – auch das ist meine Schlussfolgerung.28
Zweitens reicht die Erkennung weiter als die Behebung. ageRatingCode führt Zeilen für tvOS und watchOS; nichts, was um Einwilligung bittet, tut das.10 Diese Targets können eine geänderte Einstufung beobachten, ohne dass ein Weg dokumentiert wäre, darauf zu reagieren – und Return liefert beide aus: Die tvOS-Version 1.0.1 steht in App Store Connect auf READY_FOR_DISTRIBUTION, und die ausgelieferte iOS-App bettet eine Watch-App ein.30 Beide Lesarten setzen voraus, dass Apples Metadaten vollständig sind, was dieselben Metadaten untergraben: ageRatingCode führt keine Mac-Catalyst-Zeile, während jedes benachbarte Symbol eine hat.10
Wozu ein Server noch gut ist, wenn Apple den Start blockiert
Das Verhalten beim Widerruf beschreibt Apple in einem Satz: „Widerrufen Eltern oder Erziehungsberechtigte die Einwilligung zum Zugang ihres Kindes zu einer App, verhindert Apple den Start der App. Um Widerrufe der Einwilligung zu verarbeiten, verwenden Sie den Wert RESCIND_CONSENT aus notificationType.“8
Achten Sie auf die Reihenfolge der Teilsätze. Das System sperrt den Zugang bereits, RESCIND_CONSENT ist also kein Durchsetzungspunkt, und wer es als solchen baut, verschenkt es. Es ist das einzige Signal, das Sie über einen Benutzer erhalten, auf dessen Gerät Ihr Code nicht mehr laufen kann. Wie dieses Ereignis einzuordnen ist, sagt Apple nicht; die nächste Entsprechung, die ich gefunden habe, ist ein Antrag auf Accountlöschung: Abonnements, die abzugleichen sind, ein Zustand, der einzufrieren ist, und ein Haushalt, der wieder auftauchen kann.
Der Payload ist ungewöhnlich dünn. appData trägt vier Felder: appAppleId, bundleId, environment und signedAppTransactionInfo.3 Keine Transaktion, kein Abonnement, keine Verlängerungsdaten und keine Accountkennung aus Ihrem System. Die Verbindung zu einer Person läuft über die signierte App-Transaktion, deren appTransactionID der App Store „für jeden Apple-Account, der Ihre App lädt, und für jedes Mitglied einer Familiengruppe bei Apps mit Unterstützung für die Familienfreigabe“ erzeugt.19 Eine kostenlose App besitzt also durchaus einen dauerhaften Schlüssel pro Account, gegen den sich abgleichen lässt – und eine App, die nie einen gespeichert hat, bekommt eine Benachrichtigung, die sie niemandem zuordnen kann.
Der Transport hält keine Überraschungen bereit: eine Version-2-URL pro Umgebung in App Store Connect über TLS 1.2 oder neuer, 17.0.0.0/8 auf der Allowlist, 200 bis 206 als Erfolg und 40x oder 50x, um fünf erneute Zustellversuche nach 1, 12, 24, 48 und 72 Stunden zu erkaufen – ausschließlich in der Produktionsumgebung.2324
RESCIND_CONSENT trägt außerdem keinen Subtype. Jeder der 19 veröffentlichten Subtype-Werte ist an einen benannten Benachrichtigungstyp gebunden, und die Zeichenkette RESCIND_CONSENT taucht auf jener Seite nirgends auf.25 Aufschlussreicher noch: Apples Seite zu notificationType ordnet 40 Ereignisse in acht Tabellen unter „Handle use cases for In-App Purchase life-cycle events“ ein, und in keiner davon erscheint RESCIND_CONSENT; den Wert gibt es in der Liste der möglichen Werte und sonst nirgends auf der Seite.2 Apple hat die Benachrichtigung im Material zur Altersprüfung dokumentiert und sie nie in jene Referenz eingebunden, die ein Server-Team tatsächlich liest.
Was meine eigenen Projekte schon falsch machen
Ich habe meinen eigenen Code durchsucht, bevor ich über fremden geschrieben habe. Die Auswahlregel war mechanisch – und genau in dieser Regel steckte der Fehler: jede Zeile der Tabelle „Active Projects“ in meiner eigenen CLAUDE.md, hinter der ein Xcode-Projekt steht, was sieben Projekte und 508 Dateien ergibt, also jede Swift-Datei, jede Entitlements-Datei, jede Property List und jede project.pbxproj.31 Null Treffer für PermissionKit, AskCenter, SignificantAppUpdateTopic, FamilyControls, ManagedSettings, DeviceActivity, CKShare, sharedCloudDatabase oder ageRatingCode. Fünf der sieben haben einen Eintrag in App Store Connect. Water und Yawara haben keinen und wurden nie veröffentlicht; lesen Sie diese beiden also als Code, nicht als Apps in irgendjemandes Händen.31 Ace Citizenship sah nach dem wahrscheinlichsten Zuhause für minderjährige Benutzer aus und ist das unwahrscheinlichste: Die begleitende Website nennt als Voraussetzung für das Formular N-400 „18 Jahre oder älter“, und die App fragt nirgends nach einem Geburtsdatum.31
Anschließend habe ich dieselben Muster über jedes Repository unter ~/Projects laufen lassen – der Durchlauf, mit dem ich hätte anfangen sollen. Dieselben Muster treffen auf 21 Dateien zu, sieben davon Code, und sechs dieser sieben liegen in einem einzigen iOS-Projekt, für das das Register nie eine Zeile bekommen hat.32
Randori ist ein Trainingstagebuch für Jiu-Jitsu und enthält genau die Einwilligungsoberfläche, für deren Erkennung die Musterliste existiert: 20 Treffer für CKShare und sharedCloudDatabase über ConnectionStore.swift, RandoriApp.swift, CKPostTransport.swift, ProfileCardView.swift, CloudShareSheet.swift und SocialContracts.swift, wobei die Annahme über userDidAcceptCloudKitShareWith läuft, wenn die App bereits ausgeführt wird, und beim Kaltstart über connectionOptions.cloudKitShareMetadata.32 Randori liefert außerdem ein eigenes Einwilligungsprimitiv dafür mit, den Namen einer anderen Person zu tragen: TagConsentStore verweigert im Zweifel, sodass ein Sportler, dessen Client keine Markierungsrichtlinie veröffentlicht hat, überhaupt nicht markiert werden kann.32
Das eine Projekt mit einer echten Einwilligungsoberfläche hat sich also ein eigenes Register geschrieben und keines von Apple übernommen. Es schuldet drei Dinge, die ich nicht gebaut habe. Die Oberflächen zwischen Personen einzuschalten, die seine Verträge bislang schlafen lassen, ist der Lehrbuchfall für SignificantAppUpdateTopic. Für ageRatingCode gibt es keinen gespeicherten Ausgangswert, und eine unveröffentlichte 1.0 lief bisher nur aus Xcode, der Sandbox oder TestFlight – genau dort, wo die Eigenschaft laut Apple 0 zurückgibt.22 Und der Widerruf hat keinen Landeplatz: Randori verkauft nichts und betreibt keinen eigenen Server.32
Der interessantere Befund: Die Einwilligung der Erziehungsberechtigten wird in dreien der ursprünglichen sieben Projekte längst ausgeliefert – unter einem älteren Namen.
Ask to Buy ist derselbe Mechanismus in derselben Form, und Apple beschreibt ihn mit beinahe denselben Worten: „Mit Ask to Buy sendet das System die Kaufanfrage an die Eltern oder Erziehungsberechtigten, wenn ein Kind einen berechtigten Kauf oder Download tätigen möchte.“34 Sichtbar wird das als Product.PurchaseResult.pending, und eine Zustimmung trifft über Transaction.updates ein statt an der Aufrufstelle, weil diese Sequenz „Transaktionen empfängt, die außerhalb der App stattfinden, etwa Ask-to-Buy-Transaktionen“.35 Eine Ablehnung liefert gar nichts: „Ihre App erhält keine Transaktion, weil Sie Ask to Buy abgelehnt haben.“34
Drei der sieben verkaufen etwas, und jedes behandelt den ausstehenden Zustand anders:33
| App | Produkt | Umgang mit .pending |
|---|---|---|
| ResumeGeni | Monatliches Abonnement | Ein benanntes .pending-Ergebnis mit dokumentiertem Weg zum Abgleich |
| Reps | Abonnement, zwei Stufen | case .userCancelled, .pending: in einen Zweig zusammengelegt |
| Ace Citizenship | Nicht verbrauchbares Produkt | Ein eigener case .pending:, der false zurückgibt, identisch zum Abbruch |
Zwei von dreien melden einen überlegenden Erziehungsberechtigten als abbrechenden Benutzer, und was der Benutzer sieht, ist schlimmer als ein falsches Etikett. Reps schließt seine Paywall nur, wenn purchase true zurückgibt; Ace geht nur weiter, wenn der eigene Aufruf Erfolg meldet. Bei .pending liefert keiner der beiden Aufrufe etwas Verwertbares, also bleiben beide Paywalls offen – ohne Fehlermeldung, ohne Hinweis, ohne Ladeanzeige: ein Tipp ins Leere.33 Minuten später stimmt das Elternteil zu, und die Transaktion landet in einem Listener, dessen Oberfläche nie zur Kenntnis genommen hat, dass überhaupt eine Anfrage lief.
Der zusammengelegte Zweig ist exakt der Fehler, zu dem PermissionKit bei höherem Einsatz einlädt, und ich habe ihn zweimal ausgeliefert, bevor Apple dem Muster eine zweite API gegeben hat. „Ausstehend“ ist kein exotischer Zweig. „Ausstehend“ ist, wie ein Einwilligungsablauf von innerhalb einer App aussieht, und die richtige Voreinstellung ist ein Zustand, den Sie darstellen, kein Wert, den Sie zurückgeben.
Eine App hängt bereits an der Serverhälfte, was den fehlenden Zweig greifbar macht. Der Version-2-Endpunkt von ResumeGeni hat seit dem 26. Juni 2026 mindestens 56 Benachrichtigungen aufgezeichnet, 55 davon aus der Sandbox und eine aus der Produktion – daran erkenne ich, dass beide Umgebungs-URLs registriert sind und nicht nur eine. Sein Handler benennt 13 Benachrichtigungstypen und verteilt acht davon; die restlichen fünf tauchen nur in Kommentaren auf. RESCIND_CONSENT steht in keiner der beiden Gruppen und auch sonst nirgends im Repository.33
FAQ
Welche API bittet Erziehungsberechtigte um Einwilligung, und welche fragt Erwachsene?
Verschiedene Frameworks – und die Aufteilung verwechselt man leicht. Die elterliche Einwilligung läuft über PermissionKit: ein SignificantAppUpdateTopic, verpackt in PermissionQuestion(significantAppUpdateTopic:), gesendet mit PermissionButton, beantwortet über AskCenter.shared.responses(for:).12162126 Die Bestätigung durch Erwachsene läuft stattdessen über Declared Age Range, als showSignificantUpdateAcknowledgment(in:updateDescription:).27 Prüfen Sie zuerst requiredRegulatoryFeatures, denn eine erwachsene Person über PermissionKit zu fragen, wirft AskError.notAvailable.711
Wie teste ich den Widerruf der Einwilligung ohne echten Familienaccount?
Aktivieren Sie den Entwicklermodus, öffnen Sie dann „Einstellungen“, „Entwickler“, „Sandbox Apple Account“, melden Sie sich an, wählen Sie den Account aus, tippen Sie auf „Manage“ und wählen Sie „Revoke App Consent“. Geben Sie Ihren Bundle Identifier ein und tippen Sie auf „Revoke Consent“; das System zeigt „Notification Triggered“.11 Ist eine Version-2-URL konfiguriert, empfängt Ihr Server RESCIND_CONSENT mit einem appData-Objekt, dessen Felder bundleId und environment bestätigen, dass die Benachrichtigung zur richtigen App gehört.311 Die Sandbox sendet jede Benachrichtigung genau einmal, ohne Wiederholung – ein Endpunkt, der mitten im Test 50x liefert, bekommt keine zweite Chance.24
Warum sollte eine App zur Laufzeit ihre eigene Alterseinstufung überwachen?
Weil Apple Einstufungen im Store ohne jede Einreichung Ihrerseits ändert – und weil Apple schreibt, das texanische Recht werte eine geänderte Einstufung als wesentliche Änderung, um Sie dann für die Einholung der elterlichen Einwilligung an die Significant Change API zu verweisen.4 Der 18. Juni 2026 ist das ausgearbeitete Beispiel: Australien verlor die Stufe 15+, Vietnam bekam ein vierstufiges Schema, beides angewandt auf bestehende Apps aus bestehenden Fragebogenantworten.937 Eine Zuordnung von der Ganzzahl der Eigenschaft zu einer Einstufungsstufe veröffentlicht Apple nicht; der Vergleich mit einem selbst gespeicherten Wert ist also die einzige Operation, die sie unterstützt.10
Sperrt RESCIND_CONSENT den Benutzer für mich?
Das tut das System bereits – und genau das übersehen die meisten Implementierungen. Apple erklärt, dass bei einem Widerruf durch Erziehungsberechtigte „Apple den Start der App verhindert“, und verweist Sie dann auf die Benachrichtigung, um das Ereignis zu verarbeiten, nicht um es durchzusetzen.8 Die verbleibende Arbeit hat also Serverform: Accountzustand einfrieren, ein etwaiges Abonnement abgleichen und keine Pushes mehr an ein Gerät senden, das Ihre App nicht öffnen kann. Behandeln Sie es wie eine Accountlöschung, nicht wie eine fehlgeschlagene Autorisierungsprüfung.
Die wichtigsten Erkenntnisse
Für iOS-Entwickler:
- Prüfen Sie noch heute Ihr bestehendes switch über Product.PurchaseResult. Ask to Buy ist bereits ausgelieferte Einwilligung der Erziehungsberechtigten, .pending ist ihre Erscheinungsform, und diesen Fall mit .userCancelled zusammenzulegen ist genau der Defekt, zu dem PermissionKit bei höherem Einsatz einlädt.3435
- Rechnen Sie mit iOS 26.5, nicht mit 26.4, wenn Ihr Ablauf zwischen einer bestätigten und einer selbst angegebenen erwachsenen Person unterscheidet.36
- Reparieren Sie das return in Apples Beispiel-Listener, bevor Sie ihn kopieren, und lassen Sie niemals 0 in Ihren gespeicherten Ausgangswert für ageRatingCode gelangen.622
Für Teams, die auf mehreren Apple-Plattformen ausliefern:
- Prüfen Sie die Verfügbarkeitszeilen, bevor Sie die Arbeit planen. Eine native macOS-App kann erkennen, dass die Bestätigung durch Erwachsene gilt, und hat keine API, um sie anzuzeigen; tvOS und watchOS können ageRatingCode lesen, ohne dass dahinter eine API für die Einwilligung stünde.71027
- Speichern Sie die Bestätigung pro Änderung in NSUbiquitousKeyValueStore und nutzen Sie AppTransaction.originalAppVersion, um Neuinstallationen von Änderungen auszunehmen, die vor ihnen liegen.619
Für Backend- und Release-Verantwortliche:
- Erfassen Sie appTransactionID pro Account, bevor Sie ihn brauchen, und stellen Sie den Version-2-Endpunkt auch für eine kostenlose App bereit. Ein nachträglich gebauter Endpunkt empfängt Widerrufsereignisse, die er niemandem zuordnen kann.319
- Lassen Sie die Beschreibung der wesentlichen Änderung von der Person gegenlesen, die für Ihre Produkttexte verantwortlich ist. Es ist der einzige Text, den Erziehungsberechtigte lesen, während sie entscheiden, ob Ihre App einen Benutzer behält.12
Drei der vier Durchsetzungspunkte dieses Zyklus greifen bei etwas, das Sie steuern: der Launch-Screen-Schlüssel bei einem SDK, das @State-Makro bei einer Toolchain und die Social-Media-Angabe bei einer Einreichung. Die Einwilligung der Erziehungsberechtigten greift bei einem Gerichtsverfahren und einer Einstufungstabelle im Store. Die vollständige Übersicht der Reihe ist die Apple-Ecosystem-Serie.
Quellen
-
Apple, App Store Server Notifications changelog. Unter der Überschrift zum 4. November 2025, New features: „Das
responseBodyV2DecodedPayloadwurde um das neue Payload-ObjektappDataerweitert“ und „Der BenachrichtigungstypRESCIND_CONSENTwurde zunotificationTypehinzugefügt.“ Die beiden folgenden Einträge im Changelog datieren auf den 10. Dezember 2025 und den 27. April 2026, keiner davon berührt die Einwilligung. Gelesen aus dem JSON von Apples Dokumentation am 26. Juli 2026, da die HTML-Seite über JavaScript gerendert wird. ↩ -
Apple, notificationType, App Store Server Notifications. Quelle für die Definition von
RESCIND_CONSENT(„Ein Benachrichtigungstyp, der anzeigt, dass die Eltern oder Erziehungsberechtigten ihre Einwilligung in die App-Nutzung durch ein Kind widerrufen haben“) und für die hier verwendete Zählung: Die Seite führt 23 mögliche Werte (CONSUMPTION_REQUEST, DID_CHANGE_RENEWAL_PREF, DID_CHANGE_RENEWAL_STATUS, DID_FAIL_TO_RENEW, DID_RENEW, EXPIRED, EXTERNAL_PURCHASE_TOKEN, GRACE_PERIOD_EXPIRED, METADATA_UPDATE, MIGRATION, OFFER_REDEEMED, ONE_TIME_CHARGE, PRICE_CHANGE, PRICE_INCREASE, REFUND, REFUND_DECLINED, REFUND_REVERSED, RENEWAL_EXTENDED, RENEWAL_EXTENSION, RESCIND_CONSENT, REVOKE, SUBSCRIBED, TEST). Die ZeichenketteRESCIND_CONSENTkommt im Payload der Seite genau einmal vor, innerhalb der Liste der möglichen Werte; die acht Tabellen unter „Handle use cases for In-App Purchase life-cycle events“ tragen zusammen 40 Ereigniszeilen (4, 6, 7, 7, 8, 6, 6 und 4 Zeilen einschließlich der jeweiligen Kopfzeile), und keine davon nennt ihn. Beachten Sie, dassREVOKEden Verlust einer Berechtigung aus der Familienfreigabe bezeichnet und keinen Widerruf einer Einwilligung: „ein In-App-Kauf, zu dem der Kunde über die Familienfreigabe berechtigt war, ist über die Freigabe nicht mehr verfügbar.“ Gelesen aus dem JSON von Apples Dokumentation am 26. Juli 2026. ↩↩↩↩ -
Apple, appData, App Store Server Notifications, eingeführt mit Version 2.19. Quelle für „Das
appData-Objekt ist Bestandteil desresponseBodyV2DecodedPayload. Dieses Objekt ist im Payload enthalten, wenn dernotificationTypeRESCIND_CONSENTlautet“ sowie für die vier Eigenschaften:appAppleId(„verfügbar für Apps, die Benutzer aus dem App Store laden. In der Sandbox-Umgebung ist sie nicht vorhanden“),bundleId,environmentundsignedAppTransactionInfo(eineJWSAppTransaction). Die Seite responseBodyV2DecodedPayload benennt die Exklusivität unabhängig davon und beschreibtappDataals Feld, das „erscheint, wenn dernotificationTypeRESCIND_CONSENTlautet“, mit dem Zusatz: „Die Felderdata,appData,summaryundexternalPurchaseTokenschließen einander aus. Der Payload enthält nur eines dieser Felder.“ Diese beiden Seiten sind die Grundlage dafür,RESCIND_CONSENTals einzigen Benachrichtigungstyp zu bezeichnen, dessen PayloadappDataträgt; die ZeichenketteappDatataucht auf der Seite zunotificationTypenirgends auf. ↩↩↩↩ -
Apple, Next steps for apps distributed in Texas, Apple Developer News, 4. November 2025. Quelle für die texanischen Alterskategorien („unter 13, 13-15, 16-17 oder über 18“), für den von Apple verwendeten Framework-Namen („die Significant Change API unter dem Framework PermissionKit“), für den Satz zur Entwicklerverantwortung („Es liegt in der Verantwortung des Entwicklers zu bestimmen, wann eine wesentliche Änderung an seiner App vorliegt“), für das Beispiel zur Alterseinstufung („Das texanische Recht betrachtet eine Änderung der Alterseinstufung einer App als wesentliche Änderung, und Entwickler sollten ihre Angaben zur Alterseinstufung in App Store Connect aktuell halten. Aktualisiert ein Entwickler die Alterseinstufung seiner App, wird die Einstufung auf allen Benutzergeräten aktualisiert, sobald die Version live ist“), für die StoreKit-Einordnung („Entwickler können einen neuen Eigenschaftstyp in StoreKit verwenden, um automatisch zu prüfen, wann sich die Alterseinstufung ihrer App auf dem Gerät eines Benutzers geändert hat, und anschließend über die Significant Change API die elterliche Einwilligung einholen“), für das Verhalten beim Widerruf („Eltern oder Erziehungsberechtigte in Texas können ihre Einwilligung für jede App zurückziehen, was den Start der App auf dem Gerät des Kindes oder Jugendlichen blockiert“) sowie für die vierteilige Liste unter „Next steps“. Ebenfalls Quelle für die Datierung der Beta-Verfügbarkeit auf iOS 26.2 und iPadOS 26.2. Abgerufen am 26. Juli 2026. ↩↩↩↩↩↩↩↩↩
-
Apple, Update for Apps Distributed in Texas, Apple Developer News, 3. Juni 2026. Quelle für die aufgehobene einstweilige Verfügung („Aufgrund einer kürzlich ergangenen Gerichtsentscheidung, die eine einstweilige Verfügung gegen das texanische Gesetz SB 2420 aufhebt, unterliegen neue Apple-Accounts in Texas jetzt dem Gesetz“), für den Geltungsbereich („Altersprüfung und Einwilligung der Eltern oder Erziehungsberechtigten im Namen Minderjähriger unter 18 Jahren für Downloads, Apple-In-App-Käufe und wesentliche Änderungen im Zusammenhang mit einer App. Eltern oder Erziehungsberechtigte können ihre Einwilligung für jede App, die sie zuvor für ihr Kind genehmigt haben, außerdem widerrufen“), für das Inkrafttreten („Diese Änderungen treten ab dem 4. Juni 2026 in Kraft“), für den wiederholten Hinweis auf die Entwicklerverantwortung und für dieselbe vierteilige Umsetzungsliste. Abgerufen am 26. Juli 2026. ↩↩↩↩↩↩
-
Apple, Implementing age assurance and permissions, Beispielcode zu Declared Age Range. Verfügbarkeit: iOS 26.5, iPadOS 26.5, Mac Catalyst 26.5, Xcode 27.0 Beta; der Artikel weist an, sich vor dem Ausführen „auf einem Gerät mit iOS 26.4 oder neuer“ bei iCloud anzumelden. Quelle für das Verhalten bei leerer Menge („Ist keine der beiden Funktionen vorhanden, überspringt die App den Ablauf vollständig“), für die Altersschwelle 18, für die vier ausgewerteten Kategorien (
.minor,.verifiedAdult, beschrieben als „eine erwachsene Person mit bestätigter Zahlungsmethode“,.unverifiedAdultals „eine erwachsene Person ohne Accountverifizierung“,.declinedSharing), für das Ergebnis bei nicht verifizierten Erwachsenen („die App setzt die Phase auf.blockedund verhindert den Zugang, bis die Person ihren Account in den Einstellungen verifiziert“), für den Weg bei Minderjährigen mitSignificantAppUpdateTopicundPermissionQuestion, für das Senden perPermissionButton, für das hier wörtlich zitierte Codebeispiel des ListenersAskCenter.shared.responses(for:), für das Verhalten bei Ablehnung („Lehnt das Elternteil die Anfrage ab, verhindert die App die Nutzung durch die minderjährige Person“), für die Nachverfolgung der Bestätigung überNSUbiquitousKeyValueStoremitdidChangeExternallyNotification(„damit andere Geräte denselben Ablauf nicht erneut zeigen“) und für die Ausnahme überoriginalAppVersion(„Personen, die die App installieren, wenn eine wesentliche Änderung bereits vorhanden ist, müssen sie nicht bestätigen“). Das Projekt setzt außerdem die Capability Declared Age Range und den iCloud-Dienst für Schlüssel-Wert-Speicher voraus. Gelesen aus dem JSON von Apples Dokumentation am 26. Juli 2026. ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple, AgeRangeService.requiredRegulatoryFeatures und AgeRangeService.RegulatoryFeature, Declared Age Range. Beide verfügbar ab iOS 26.4, iPadOS 26.4, Mac Catalyst 26.4 und macOS 26.4, ohne Zeile für visionOS, tvOS oder watchOS. Deklaration:
var requiredRegulatoryFeatures: Set<AgeRangeService.RegulatoryFeature> { get async throws }, wirftnotAvailable, „wenn der Dienst der regulatorischen Funktion nicht verfügbar ist“. Das Enum führt genau drei Fälle:declaredAgeRangeRequired(„Zeigt an, dass die Person ihre Altersspanne mit Ihrer App teilen muss“),significantAppChangeRequiresAdultNotification(„Zeigt an, dass erwachsene Benutzer die wesentliche Änderung Ihrer App bestätigen müssen“) undsignificantAppChangeRequiresParentalConsent(„Zeigt an, dass Eltern oder Erziehungsberechtigte eine wesentliche App-Änderung bestätigen und ihr zustimmen müssen“). ↩↩↩↩↩↩ -
Apple, Age assurance frameworks Q&A, Apple Developer Support. Quelle für die SDK-Untergrenze („Sie müssen Ihre App gegen die SDKs von iOS 26.2 und iPadOS 26.2 oder neuer mit Xcode 26.2 (17C52) oder neuer bauen“), für die Ausnahme bestehender Accounts („Bestehende Apple-Accounts unter iOS 18 und iPadOS 18 oder älter … sind nicht betroffen“, ein Satz, dessen ausgelassener Teil „einschließlich Erwachsenen- und Kinderaccounts für Kinder und Jugendliche“ präzisiert), für die Antwort zur Verantwortung („Ja, Entwickler sind für ihre eigenen Altersbeschränkungen verantwortlich“ und „Wenden Sie sich bei Fragen zu Ihren Compliance-Pflichten an Ihre Rechtsberatung“), für die in diesem Artikel zweimal zitierte regionale Eingrenzung („In bestimmten Regionen, in denen es gesetzlich vorgeschrieben ist, verwendet Apple Methoden der Altersprüfung, um das Alter des Inhabers eines Apple-Accounts zu bestätigen, und teilt Alterskategorien über die Declared Age Range API mit Ihnen. In diesen Regionen müssen Sie das Alter der Personen prüfen, die Ihre App verwenden“, später erneut formuliert als „In Regionen, in denen es gesetzlich vorgeschrieben ist, müssen Sie das Alter der Personen, die Ihre App verwenden, mit der Declared Age Range API prüfen“), für die Zugangspflicht („Bei wesentlichen App-Updates sind Sie dafür verantwortlich, den Zugang zu Ihrer App oder zu einzelnen Funktionen zu verhindern, wo dies erforderlich ist, und die Antwort der Eltern oder Erziehungsberechtigten zu verarbeiten. Bis die Eltern ihre Einwilligung erteilen, muss dem Kind der Zugang zum wesentlichen Update verwehrt bleiben, was sämtliche App- und Accountdaten oder einzelne Funktionen umfassen kann“), für das Verhalten beim Widerruf („Widerrufen Eltern oder Erziehungsberechtigte die Einwilligung zum Zugang ihres Kindes zu einer App, verhindert Apple den Start der App. Um Widerrufe der Einwilligung zu verarbeiten, verwenden Sie den Wert
RESCIND_CONSENTausnotificationType“), für die Antwort zum App Review („Nein, am App-Review-Prozess ändert sich nichts“) und für die Antwort zu Nutzungsbedingungen und Datenschutz („Das kommt darauf an. Sie bestimmen anhand der geltenden Gesetze, was ein wesentliches App-Update darstellt“). Gelesen am 26. Juli 2026. ↩↩↩↩↩↩↩↩↩ -
Apple, Upcoming changes to age ratings in Australia and Vietnam, Apple Developer News, 21. Mai 2026. Quelle für „Ab dem 18. Juni 2026 werden die Alterseinstufungen im App Store in Australien und Vietnam aktualisiert“, für die australische Änderung („Die Alterseinstufung 15+ wird im App Store in Australien nicht mehr verfügbar sein. Apps, die derzeit mit 15+ eingestuft sind und die folgenden Inhaltsdeskriptoren tragen, werden auf 16+ aktualisiert“) samt ihrer drei Deskriptoren (uneingeschränkter Webzugang; häufige medizinische Informationen oder Behandlungshinweise; Lootboxen) sowie für die vietnamesische Änderung („Um Artikel 38 des vietnamesischen Dekrets 147 zu entsprechen, benötigen Apps, die im App Store in Vietnam verfügbar sind, eine regionsspezifische Alterseinstufung. Auf Grundlage Ihrer Antworten im Fragebogen zur Alterseinstufung in App Store Connect erhält Ihre App eine von vier Einstufungen (00+ (alle Altersgruppen), 12+, 16+ oder 18+)“). Keine der beiden Änderungen verlangt vom Entwickler die Einreichung eines Builds. Abgerufen am 26. Juli 2026. ↩↩↩
-
Apple, AppStore.ageRatingCode, StoreKit. Deklaration
static var ageRatingCode: Int? { get async }, verfügbar ab iOS 26.2, iPadOS 26.2, macOS 26.2, tvOS 26.2, visionOS 26.2 und watchOS 26.2, ohne Zeile für Mac Catalyst. Rückgabewert: „Eine Ganzzahl, die den aktuellen Code der Alterseinstufung darstellt, odernil, wenn die Alterseinstufung nicht verfügbar ist.“ Quelle für die Einordnung als Vergleich („Verwenden Sie diese Eigenschaft, um die Alterseinstufung Ihrer App abzurufen und mit der zuletzt bekannten Einstufung zu vergleichen, um zu prüfen, ob sie sich geändert hat“) sowie für die Verkettung mit PermissionKit („Hat sich die Alterseinstufung Ihrer App geändert, ziehen Sie in Betracht, Eltern oder Erziehungsberechtigte über die Significant Change API zu informieren“) – ein Satz, in dem „Significant Change API“ der Linktext ist und Apples Seite zuSignificantAppUpdateTopicdas Linkziel. Apples eigenes Beispiel auf der Seite ist einguard letum die Eigenschaft, das eine Meldung ausgibt, wenn der Wert nicht verfügbar ist. Am 26. Juli 2026 wurde Apples Dokumentation nach einer Zuordnung dieser Ganzzahlen zu Einstufungsstufen (4+, 9+, 13+, 16+, 18+) durchsucht: weder auf dieser Seite noch auf der Seite zum TypAppStorenoch in der Referenz zu Alterseinstufungen in der Hilfe zu App Store Connect findet sich eine. ↩↩↩↩↩↩↩↩↩ -
Apple, Testing age assurance in sandbox, StoreKit. Quelle für den Weg auf dem Gerät („Einstellungen“, „Entwickler“, „Sandbox Apple Account“, „Manage“, dann „Age Assurance or Revoke App Consent“), für die sechszeilige Testmatrix, deren Zeilen ab 18 eine untere Grenze von 18 ohne obere Grenze und eine Altersangabe von
selfDeclaredoderconfirmedzurückgeben, für das Verhalten beim Fragen Erwachsener („Für Testfälle ab 18 wirft PermissionKitAskError.notAvailable, statt einePermissionChoicezurückzugeben. Der Aufruf vonAskCenter.ask(_:)für einen erwachsenen Benutzer wirft diesen Fehler, weil er die Voraussetzungen für elterliche Erlaubnisanfragen nicht erfüllt“), für die Schritte zum Widerruf, die mit der Bestätigung „Notification Triggered“ enden, samt „Eine Benachrichtigung wird in Kürze an den Entwicklerserver gesendet“, sowie für den Hinweis zum Payload („Ihr Server empfängt einennotificationTypeRESCIND_CONSENT. Der Benachrichtigungs-Payload enthält einappData-Objekt mit App-Metadaten, darunter die FelderbundleIdundenvironment“). Die drei Zeilen für Minderjährige in der Matrix sind: unter 13 genehmigt, 13 bis 15 genehmigt und 16 bis 17 abgelehnt, alle mit der AltersangabeguardianDeclared. ↩↩↩↩↩ -
Apple, SignificantAppUpdateTopic, PermissionKit. Verfügbar ab iOS 26.2, iPadOS 26.2, Mac Catalyst 26.2, macOS 26.2 und visionOS 26.2; deklariert als
struct SignificantAppUpdateTopic, konform zuQuestionTopic, mitinit(description: String). Quelle für das Zurückreichen der Definition („Sie bestimmen anhand der geltenden Vorschriften, was ein wesentliches Update darstellt“), für die Hinweise zur Beschreibung („Verwenden Sie eine knappe, verständliche Sprache, die klar erklärt, was sich in Ihrer App geändert hat. Eltern und Erziehungsberechtigte sehen diese Beschreibung, wenn sie über die Erteilung der Erlaubnis entscheiden“) und für beide Codekommentare im hier wörtlich wiedergegebenen Beispiel „Specific/Vague“. ↩↩↩↩↩↩ -
Apple, New requirements for apps available in Texas, Apple Developer News, 8. Oktober 2025. Quelle für die ursprüngliche Ankündigung („Ab dem 1. Januar 2026 führt ein neues Gesetz des Bundesstaates Texas … Anforderungen an die Altersprüfung für App-Marktplätze und Entwickler ein“, wobei der ausgelassene Teil SB2420 benennt), für die Voraussetzung der Familienfreigabe („Alle neuen Apple-Accounts für Benutzer unter 18 Jahren müssen einer Familienfreigabe-Gruppe beitreten, und Eltern oder Erziehungsberechtigte müssen für sämtliche App-Store-Downloads, App-Käufe und Transaktionen des Minderjährigen über Apples In-App-Kaufsystem ihre Einwilligung erteilen“) sowie für die Vorankündigung zu Utah und Louisiana („Ähnliche Anforderungen treten im Lauf des nächsten Jahres in Kraft“). Abgerufen am 26. Juli 2026. ↩
-
Apple, Update on age requirements for apps distributed in Texas, Apple Developer News, 23. Dezember 2025. Quelle für die einstweilige Verfügung („Eine kürzlich von einem Bezirksgericht erlassene einstweilige Verfügung hat die Durchsetzung des texanischen Gesetzes SB2420 ausgesetzt … Angesichts dieser Entscheidung wird Apple die zuvor angekündigten Umsetzungspläne pausieren und den laufenden Rechtsprozess beobachten“), für die weiterhin bestehende Verfügbarkeit aller vier Werkzeuge in der Sandbox und für ihre Ausweitung auf Utah und Louisiana. Abgerufen am 26. Juli 2026. ↩↩
-
Apple, Age requirements for apps distributed in Brazil, Australia, Singapore, Utah, and Louisiana, Apple Developer News, 24. Februar 2026. Quelle für die Download-Beschränkung ab 18 („Ab dem 24. Februar 2026 blockiert Apple Benutzer in Australien, Brasilien und Singapur beim Laden von Apps mit der Einstufung 18+, sofern nicht durch angemessene Methoden bestätigt wurde, dass es sich um Erwachsene handelt. Der App Store führt diese Bestätigung automatisch durch. Entwickler können jedoch gesonderte Pflichten haben, eigenständig zu bestätigen, dass ihre Benutzer erwachsen sind“), für die Daten zu Utah und Louisiana („Für Benutzer mit neuen Apple-Accounts in Utah ab dem 6. Mai 2026 und in Louisiana ab dem 1. Juli 2026 werden Alterskategorien auf Anfrage über die Declared Age Range API mit der App des Entwicklers geteilt“), für den in diesem Artikel zitierten Satz zur Erweiterung samt der vier darauf folgenden Links („Die zuvor angekündigten Werkzeuge wurden erweitert, um Entwickler bei der Erfüllung der Compliance-Pflichten für Louisiana und Utah zu unterstützen, darunter:“ Declared Age Range API, Significant Change API unter PermissionKit, neuer Eigenschaftstyp zur Alterseinstufung in StoreKit, App Store Server Notifications), für die Folge zu Lootboxen in Brasilien sowie für die erste öffentliche Nennung der Significant Update Action („Entwickler können die Declared Age Range API verwenden, um Erwachsenen in diesen Bundesstaaten über die Significant Update Action, jetzt in der Beta, Hinweise auf wesentliche Updates anzuzeigen“). Abgerufen am 26. Juli 2026. ↩↩↩↩↩
-
Apple, PermissionQuestion und expirationDate, PermissionKit.
final class PermissionQuestion<Topic> where Topic : QuestionTopic, verfügbar ab iOS 26.0 mit vier Initialisierern:init(handle:),init(handles:),init(communicationTopic:)undinit(significantAppUpdateTopic:), letzterer eingeführt mit iOS 26.2 und beschrieben als Erzeugung „einer Erlaubnisfrage, die Eltern oder Erziehungsberechtigte um die Erlaubnis bittet, Ihre App nach einem wesentlichen Update weiter zu verwenden“.expirationDateist deklariert alsfinal var expirationDate: Date?mit der Erläuterung „Ist das Datum verstrichen, kann die Person, welche die Frage erhält, nicht mehr antworten.“ Einen Standardwert für die Eigenschaft veröffentlicht Apple nicht, ebenso wenig eine Empfehlung zum Setzen für das Thema „wesentliches Update“. ↩↩ -
Apple, Creating a communication experience, PermissionKit. Quelle für das hier zitierte Verhalten beim Abbruch: „Zu jedem Zeitpunkt im Ablauf der Sendeanfrage hat das Kind die Möglichkeit, die Anfrage abzubrechen und sich dagegen zu entscheiden, die Frage an seine Eltern oder Erziehungsberechtigten zu senden. In diesem Fall stellt das System der aufrufenden App für diese Frage keine Antwort zu.“ Ebenfalls Quelle für die iMessage-Beschränkung des Frameworks, die die Einstiegsseite zu PermissionKit als wichtigen Hinweis führt: „Kommunikationserlebnisse mit dem Framework
PermissionKitsind ausschließlich über iMessage verfügbar.“ Beachten Sie, dass der Artikel nur den Ablauf mitCommunicationTopicdokumentiert; für den Ablauf beim wesentlichen Update veröffentlicht Apple keinen entsprechenden Artikel, und die Codebeispiele des Artikels rufenCommunicationLimits.current.permissionResponsesauf, ein Symbol, das in Apples Dokumentation zum 26. Juli 2026 einen 404 zurückgibt. ↩ -
Apple, AskError, PermissionKit.
enum AskError, konform zuLocalizedError, mit sechs Fällen. Vier tragen eine Kurzbeschreibung und kommen mit iOS 26.1:unknown,communicationLimitsNotEnabled(„Zeigt an, dass Kommunikationslimits nicht aktiviert sind, um Erlaubnisanfragen zu senden“),contactSyncNotSetupundinvalidQuestion. Zwei veröffentlichen auf ihrer eigenen Seite keine Kurzbeschreibung:systemError(underlyingError:)mit iOS 26.1 und notAvailable mit iOS 26.2, gemeinsam mitSignificantAppUpdateTopic. Die Bedeutung vonnotAvailableerscheint nur im Sandbox-Testartikel, zitiert in Anmerkung 11;systemErrorbenennt seine Ursache immerhin in der Signatur. ObcommunicationLimitsNotEnabledodercontactSyncNotSetupauch bei einer Anfrage zu einem wesentlichen Update auftreten können, bleibt unausgesprochen. ↩ -
Apple, appTransactionID und originalAppVersion zu
AppTransaction, StoreKit. Quelle für die Semantik der Kennung („Der App Store erzeugt eine einzige, global eindeutigeappTransactionIDfür jeden Apple-Account, der Ihre App lädt, und für jedes Mitglied einer Familiengruppe bei Apps mit Unterstützung für die Familienfreigabe“), für ihre Beständigkeit über erneutes Laden, Erstattung, Neukauf und Storefront-Wechsel hinweg, für ihr Vorkommen in den Payloads der App Store Server Notifications Version 2 und für den entscheidenden Satz zu kostenlosen Apps: „DieappTransactionIDist verfügbar, selbst wenn ein Kunde keine In-App-Käufe tätigt.“originalAppVersionist „die App-Version, die der Kunde ursprünglich im App Store erworben hat“, trägt unter macOSCFBundleShortVersionStringund sonstCFBundleVersionund ist in der Sandbox-Umgebung stets1.0. Der entsprechende serverseitige Typ ist appTransactionId in der App Store Server API, eingeführt mit Version 1.15. ↩↩↩↩↩ -
Apple, CommunicationLimits und updates, PermissionKit.
updatesist deklariert alsfinal var updates: some AsyncSequence<PermissionResponse<CommunicationTopic>, Never> { get }und zusammengefasst als „Registriert das Kommunikationsthema beim System, damit Ihre App bei Bedarf im Hintergrund gestartet werden kann, um Aktualisierungen zu Erlaubnissen zu empfangen.“ Apples Dokumentation führtupdatesund beide Überladungen vonCommunicationLimits.ask(_:in:)unter der Überschrift „Deprecated APIs“; die Klasse selbst bleibt fürisKnownHandle(_:)undknownHandles(in:)aktuell. Die ersetzende Sequenz lässt das Versprechen fallen: Weder die Kurzbeschreibung noch die Erläuterung zuAskCenter.responses(for:)erwähnt den Start im Hintergrund überhaupt – genau die Dokumentationslücke, auf die der Fließtext hinweist. ↩ -
Apple, AskCenter und responses(for:), PermissionKit, beide verfügbar ab iOS 26.2, iPadOS 26.2, Mac Catalyst 26.2, macOS 26.2 und visionOS 26.2.
AskCenterist einefinal class, erreichbar überstatic let shared, beschrieben als Instanz, die „Ihre Fragen über die passenden Kanäle der Familienfreigabe leitet“ und „Antworten an Ihre App zurückgibt, wenn Eltern ihre Entscheidungen treffen“.responses(for:)ist deklariert alsfinal func responses<Topic>(for topicType: Topic.Type) -> some AsyncSequence<PermissionResponse<Topic>, Never> where Topic : QuestionTopicund zusammengefasst als „Registriert den Themen-Typ beim System und gibt eine asynchrone Sequenz von Antworten zurück“, ohne jede Erwähnung eines Starts im Hintergrund. Es existieren vier Überladungen vonask(_:in:): zwei mitUIViewControllerunter iOS, iPadOS und visionOS sowie zwei mitNSWindowunter macOS, je eine pro Themen-Typ.PermissionResponselegtchoiceundquestionoffen;PermissionChoice.Answerveröffentlicht genau zwei Fälle,approvalunddenial. ↩↩ -
Antwort von Apple Staff auf AppStore.ageRatingCode always returns 0 on real device, Apple Developer Forums. Ursprünglicher Beitrag von April 2026, der
0auf einem physischen Gerät unter iOS 26.4 mit angemeldetem Sandbox-Account und in App Store Connect konfigurierter Alterseinstufung meldet. Die Antwort eines als Apple Staff gekennzeichneten Autors lautet: „Die APIageRatingCodesollte verwendet werden, um Änderungen der Alterseinstufung Ihrer App über die Zeit zu beobachten, indem sie mit dem zuletzt bekannten Wert verglichen wird. Hat sich der Code der Alterseinstufung Ihrer App geändert, ziehen Sie in Betracht, Eltern oder Erziehungsberechtigte über die Significant Change API zu informieren“, sowie „Ein Wert von0ist während der Entwicklung Ihrer App zu erwarten, wenn sie aus Xcode und in Sandbox-Umgebungen (einschließlich TestFlight) gebaut und ausgeführt wird.“ Zweimal am 26. Juli 2026 mit identischem Wortlaut abgerufen; das Forum wird über JavaScript gerendert und zeigt das Alter der Antwort als relative Zeitangabe „1w“ statt als Datum, weshalb hier kein Veröffentlichungsdatum genannt wird. Eine Forenantwort ist schwächere Evidenz als eine Dokumentationsseite, und Apples Dokumentation zuageRatingCodeerwähnt den Wert0überhaupt nicht. Die in diesem Artikel gezogene Folgerung, dass eine als Ausgangswert gespeicherte0beim ersten App-Store-Build eine falsche Änderung erzeugt, ist meine Schlussfolgerung aus jener Antwort und aus Apples dokumentiertem Vergleichsmuster. ↩↩↩↩ -
Apple, Enabling App Store Server Notifications. Quelle für die TLS-Untergrenze („Ihr Server muss das Protokoll Transport Layer Security (TLS) 1.2 oder neuer unterstützen“), für die Konfiguration je Umgebung in App Store Connect, für die Port-Vorgabe (443 oder 1024 und höher) und für das Subnetz auf der Allowlist („fügen Sie die IP-Adressen des Subnetzes
17.0.0.0/8hinzu“, was „sowohl für die Sandbox- als auch für die Produktionsumgebung gilt“). Der begleitende Artikel Receiving App Store Server Notifications beschreibt das JWS-signiertesignedPayloadund erwähnt zum 26. Juli 2026 lediglich dasdata-Objekt, ohne aufappDatazu verweisen. ↩ -
Apple, Responding to App Store Server Notifications. Quelle für die Erfolgscodes („Senden Sie HTTP
200oder einen beliebigen HTTP-Code zwischen200und206“), für den Auslöser erneuter Zustellversuche („Senden Sie HTTP50xoder40x, damit der App Store die Benachrichtigung erneut zustellt“), für den Zeitplan der Wiederholungen in Version 2 („er wiederholt fünfmal, 1, 12, 24, 48 und 72 Stunden nach dem vorherigen Versuch“), für die Einschränkung in der Sandbox („Erneute Zustellversuche gibt es nur in der Produktionsumgebung. In der Sandbox-Umgebung versucht der App-Store-Server einmal, die Benachrichtigung zu senden“) und für den Wiederherstellungsweg überGet-Notification-History. ↩↩ -
Apple, subtype, App Store Server Notifications. Die Seite führt 19 mögliche Werte (ACCEPTED, ACTIVE_TOKEN_REMINDER, AUTO_RENEW_DISABLED, AUTO_RENEW_ENABLED, BILLING_RECOVERY, BILLING_RETRY, CREATED, DOWNGRADE, FAILURE, GRACE_PERIOD, INITIAL_BUY, PENDING, PRICE_INCREASE, PRODUCT_NOT_FOR_SALE, RESUBSCRIBE, SUMMARY, UPGRADE, UNREPORTED, VOLUNTARY), jeder an einen benannten Benachrichtigungstyp gebunden. Die Zeichenkette
RESCIND_CONSENTtaucht im Payload der Seite nirgends auf, gelesen am 26. Juli 2026. ↩ -
Apple, PermissionButton, PermissionKit.
@MainActor @preconcurrency struct PermissionButton<Topic, Label> where Topic : QuestionTopic, Label : View, verfügbar ab iOS 26.2, iPadOS 26.2, Mac Catalyst 26.2, macOS 26.2 und visionOS 26.2, mit zwei Überladungen voninit(question:label:), eingeschränkt aufCommunicationTopicbeziehungsweiseSignificantAppUpdateTopic. Er löstCommunicationLimitsButtonab, den Apple auf der Framework-Seite unter „Deprecated APIs“ führt. ↩↩↩ -
Apple, AgeRangeService.showSignificantUpdateAcknowledgment(in:updateDescription:), SignificantUpdateAction sowie der SwiftUI-Environment-Wert showSignificantUpdateAcknowledgment. Die Methode ist deklariert als
@MainActor func showSignificantUpdateAcknowledgment(in windowScene: UIWindowScene, updateDescription: String) async throwsund führt iOS 26.4, iPadOS 26.4 und Mac Catalyst 26.4, ohne macOS-Zeile;AgeRangeServicelistet unter „Displaying update acknowledgments“ nur diese eine Überladung.SignificantUpdateActionund der Environment-Wert führen dieselben drei Plattformen. Apples wichtiger Hinweis zur Methode: „Prüfen Sie vor dem Aufruf dieser FunktionRegulatoryFeature, um festzustellen, ob eine Person Ihre wesentliche App-Änderung bestätigen muss.“ Die Erläuterung zum Environment-Wert ergänzt, Sie sollten „diese Action aus einemButtonoder ausonAppear(perform:)aufrufen“. ↩↩↩↩ -
Apple, requestAgeRange(ageGates:::in:), Declared Age Range. Apple veröffentlicht zwei Überladungen: eine mit
in viewController: UIViewControllerunter iOS 26.0, iPadOS 26.0 und Mac Catalyst 26.0 sowie eine mitin window: NSWindowunter macOS 26.0. Die Existenz einerNSWindow-Variante für die Altersspannen-Anfrage und ihr Fehlen beim Bestätigungs-Sheet aus Anmerkung 27 ist die Grundlage dafür, die macOS-Auslassung als Lücke und nicht als bewusste Entscheidung zu lesen; Apple hat sich in keine Richtung geäußert. ↩ -
Apple, Requesting people’s age range information in your app, Declared Age Range. Quelle für die im Fließtext zitierte Arithmetik der Schwellen („Sie können bis zu drei Altersschwellen angeben, die bis zu vier mögliche Altersspannen ergeben“), für den Mindestabstand („Jede Spanne muss mindestens zwei Jahre umfassen“) und für die Bedeutung der Grenzen („Ist der Wert
lowerBoundnil, liegt die Person unter Ihrer niedrigsten Altersschwelle“ und „Ist derupperBoundnil, erreicht oder überschreitet die Person Ihre höchste Altersschwelle“). Schwellen bei 13, 16 und 18 ergeben exakt die vier Spannen, die Apple für Texas veröffentlicht, und beide begrenzten Spannen erfüllen das Zwei-Jahres-Minimum: 13 bis 15 umfasst drei Jahre, 16 bis 17 zwei. Der Artikel warnt außerdem, dass die Regionen, denen der Account einer Person angehört, „die Altersschwellen bestimmen, die das System zur Rückgabe von Altersspannen verwendet, und dass diese von den in Ihrer Anfrage angegebenen Schwellen abweichen können“. Gelesen aus dem JSON von Apples Dokumentation am 26. Juli 2026. ↩ -
Erhebung des Autors, 26. Juli 2026: wie die Plattformangaben zustande kamen. Die Plattformwerte stammen aus der Build-Einstellung
SUPPORTED_PLATFORMSdes jeweiligen Projekts statt aus den Schlüsseln für Deployment-Targets, die Xcode unabhängig vom Ziel schreibt: Reps deklariertappletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulatorplus ein separates Targetwatchos watchsimulator, Ace Citizenship deklariert ausschließlichiphoneos iphonesimulator. Diese Methode meldet zu wenige Plattformen, und Return ist der Beleg: Der einzigeSUPPORTED_PLATFORMS-Wert von Return lautetiphoneos iphonesimulator macosx xros xrsimulator, während seine TV- und Watch-Targets stattdessenSDKROOT = appletvosundSDKROOT = watchostragen, sodass ein Durchlauf überSUPPORTED_PLATFORMSbeide nicht sieht. Jede Aussage „liefert Plattform X aus“ in diesem Artikel stammt daher aus App Store Connect und nicht aus einer Build-Einstellung. Return: TV_OS 1.0 und 1.0.1 beide READY_FOR_DISTRIBUTION, IOS und MAC_OS 1.0.1 ebenso, und das iOS-Target bettet über eine Phase „Embed Watch Content“ dieReturnWatch Watch App(com.941apps.Return.watchkitapp) ein – so gelangt eine Watch-App ans Handgelenk. Reps: IOS 1.1 und MAC_OS 1.1 READY_FOR_DISTRIBUTION, nie eine TV_OS-Version in diesem Zustand, und TV_OS 1.2 steht seit dem 2. Juni 2026 auf WAITING_FOR_REVIEW; Reps liefert also iOS und macOS aus. ↩ -
Erhebung des Autors, 26. Juli 2026, unter macOS 26.5.2 (Build 25F84) mit Xcode 26.6 (Build 17F113) und Swift 6.3.3. Auswahlregel, hier genannt, damit sich der Umfang prüfen und reproduzieren lässt, statt ihn glauben zu müssen: jede Zeile der Tabelle „Active Projects“ in meiner eigenen Agent-Konfiguration (
~/.claude/CLAUDE.md), hinter der ein Xcode-Projekt steht, was genau sieben ergibt:Reps,Return,Banana List(ausgeliefert als Get Bananas),Ace-Citizenship,Water,ResumeGeniAppundYawara. Die Regel ist zugleich der Fehler der Erhebung, dennRandorihat in dieser Tabelle keine Zeile – undRandorierwies sich als das Projekt, auf das es ankam. Fünf der sieben haben einen Eintrag in App Store Connect (Reps 6776044339, Return 6756242021, Get Bananas 6756241534, Ace Citizenship 6532592671, ResumeGeni 6771154645);WaterundYawaratauchen unter den 18 Apps des Accounts nirgends auf, wurden also nie eingereicht, und beide als App zu bezeichnen wäre zu viel gesagt. Anzahl der Swift-Dateien pro Projekt: 77, 57, 55, 26, 34, 71 und 143. Der Scan auf Einwilligungsmuster umfasste*.swift,*.entitlements,*.plistundproject.pbxproj: 85, 65, 63, 34, 38, 74 und 149, in der Summe 508. Um diese Zahlen zu reproduzieren, braucht es acht ausgeschlossene Verzeichnisnamen statt sechs:build,DerivedData,.build,Pods,.git,worktreesund, allein bei Reps,.venv(142 Property Lists inReps/.venvundReps/server/.venv) sowie.xcode-state-backups(18). Schließt man nur die ersten sechs aus, liest sich Reps als 245 und die Summe als 668; die Ausschlussliste trägt also, und jeder Name, von dem sie abhängt, steht hier. Die 16 Muster, alle mit Beachtung der Groß- und Kleinschreibung:PermissionKit,CommunicationLimits,AskPermission,AskCenter,SignificantAppUpdateTopic,SignificantUpdateAction,PermissionTopic,com.apple.developer.family-controls,FamilyControls,ManagedSettings,DeviceActivity,AuthorizationCenter,CKShare,sharedCloudDatabase,publicCloudDatabaseundageRatingCode. Null passende Dateien in allen sieben Projekten,AskCentereingeschlossen. Zwei Kontrollmuster durch dieselbe Pipeline lieferten Treffer (StoreKittraf drei Dateien in Reps,CKContainer|NSPersistentCloudKitContainer|SwiftDatatraf 17 in Banana List), woran ich erkenne, dass die Pipeline Dateien liest und nicht still versagt. Das Onboarding von Ace Citizenship (IntroCarouselView,WelcomeView,AddStateView,AddRepresentativeView) enthält kein Feld für Alter oder Geburtsdatum, undPrivacyInfo.xcprivacydeklariert ein leeresNSPrivacyCollectedDataTypes; die Zeile „18 Jahre oder älter“ zur Berechtigung stammt aus~/Projects/acecitizenship.app/content/blog/n400-application-guide.md. ↩↩↩ -
Erhebung des Autors, 26. Juli 2026: der weitere Durchlauf und Randori. Der weitere Durchlauf ließ dieselben 16 Muster über jedes Repository unter
~/Projectslaufen, schloss dieselben acht Namen plusnode_modulesaus, ließ von Git ignorierte Pfade aus und traf 21 Dateien. Sieben davon sind Code: sechs Swift-Dateien unterRandori/Randori/und_archive/Oishii-AI/Oishii AI/Services/CloudKitManager.swift(publicCloudDatabase, in einem archivierten Projekt). Die übrigen 14 sind Prosa oder Maschinenzustand: neun Pläne und Entwurfsdokumente zu Randori, drei Beiträge imcontent/blog/dieser Website (einer davon der Entwurf dieses Artikels), eine Übergabenotiz in Obsidian undobsidian-signals/40-Projects/blakecrosley-com/wwdc-2026/.pulse_state.json, die ein Skript schreibt und kein Mensch. Randori istcom.wayofyawara.randori, App Store Connect App 6789693294 mit Version 1.0 im Zustand PREPARE_FOR_SUBMISSION.CKShareundsharedCloudDatabasetreffen 20 Zeilen in sechs Dateien:ConnectionStore.swift(10),RandoriApp.swift(5),ProfileCardView.swift(2) sowie je eine Zeile inCKPostTransport.swift,CloudShareSheet.swiftundSocialContracts.swift.ConnectionStorebeschreibt seine eigene Form im Kopfkommentar als „eine Zone (ProfileCardZone), ein Record-Typ (ConnectionCard), eine Freigabe“, hältprivateCloudDatabaseundsharedCloudDatabasenebeneinander und implementiertaccept(_ metadata: CKShare.Metadata)in Zeile 355,ensureOutboundShare()in Zeile 547 sowie Blockieren und Entblocken pro Account.RandoriApp.swiftimplementiertuserDidAcceptCloudKitShareWithsowohl im App-Delegate (Zeile 73) als auch im Window-Scene-Delegate (Zeile 97, kommentiert mit „Warm: the app is running when the link is opened“), währendRandoriSceneDelegate.scene(_:willConnectTo:options:)in Zeile 88 unter dem Kommentar „Cold start: the invitation rides the connection options“connectionOptions.cloudKitShareMetadataausliest – deshalb ordnet der Fließtext den Kaltstart den Connection Options zu und nicht dem Annahme-Callback.TagConsentStoreist das eigene Einwilligungsregister der App, pro iCloud-Account abgegrenzt, und seine dokumentierte Voreinstellung ist restriktiv: Wer eine Richtlinie noch nicht erhalten hat, kann nicht markiert werden.Randori/Randori.entitlementsfordert CloudKit, HealthKit undaps-environmentan. Jedes Einwilligungsmuster außer den beiden zu CloudKit-Freigaben liefert in diesem Repository null Treffer, ebensoStoreKit,signedPayloadundnotificationType; die App verkauft also nichts und betreibt keinen eigenen Server, unddocs/asc-metadata.mdbereitet einen kostenlosen Preis und eine Alterseinstufung von 4+ vor. ↩↩↩↩ -
Erhebung des Autors, 26. Juli 2026: StoreKit-Aufrufstellen und Serverbelege. StoreKit erscheint in drei Projekten:
Reps/Reps/Services/RepsProStore.swift(automatisch verlängernd, zwei Stufen),Ace Citizenship/StoreKitManager.swift(ein nicht verbrauchbares Produkt) undResumeGeni/Subscription/(ein Monatsabonnement, serverseitig abgesichert). Der in der Tabelle zitierte Umgang mit.pendingsteht inRepsProStore.swift:134(case .userCancelled, .pending:), inStoreKitManager.swift:69-73(ein eigenercase .pending:, dessenreturn falsein Zeile 73 steht) und inSubscriptionStore.swift:209-212(ein benanntes Ergebnis für den ausstehenden Fall). Die Aufrufstellen sind es, die den Benutzer stranden lassen:RepsProPaywallView.swift:359-361schließt die Paywall nur innerhalb vonif await store.purchase(plan), undContentView.swift:484-485schaltet nur innerhalb vonif successfrei, sodass ein für einen ausstehenden Kauf zurückgegebenesfalsein beiden Apps nichts auf dem Bildschirm ändert. ResumeGeni erreicht stattdessenPaywallView.swift:526, einen.pending-Zweig, der den Hinweis „Waiting for approval. You’ll get access once it’s approved.“ einblendet. Der Endpunkt von ResumeGeni für App Store Server Notifications istPOST /api/appstore/notificationsin~/Projects/resumegeni/app/routers/appstore.py; einPOSTvon{"signedPayload":"probe"}liefert HTTP 400{"status":"invalid"}, was nur hinter dem Aktivierungsflag und innerhalb von Apples Prüfer für die Zertifikatskette erreichbar ist, undGETliefert 405. Beide Umgebungs-URLs sind registriert, und der Beleg dafür ist die Zustellung, kein Runbook: Die D1-Datenbank941-analytics, Tabellefunnel_events, enthält 56 Zeilen mitplatform='ios', deren Metadaten einennotification_typetragen, im Zeitraum vom 26.06.2026, 15:48:51 Uhr UTC bis zum 25.07.2026, 16:40:11 Uhr UTC, davon 55 mit demenvironmentsandboxund eine mitproduction(21.07.2026, 18:08:21 Uhr UTC). Behandeln Sie 56 als Untergrenze, denn der Dienst bildet nur fünf Ereignisnamen auf Funnel-Zeilen ab; die vier tatsächlich beobachteten Typen sind DID_RENEW (42), SUBSCRIBED (6), EXPIRED (5) und DID_CHANGE_RENEWAL_STATUS (3).app/services/app_store_notification_service.pybenennt 13 Benachrichtigungstypen, von denen acht in_funnel_event_name(Zeilen 75 bis 89) einen ausführbaren Zweig erreichen: SUBSCRIBED, OFFER_REDEEMED, DID_RENEW, REFUND, REVOKE, EXPIRED, DID_CHANGE_RENEWAL_STATUS und DID_FAIL_TO_RENEW. Die anderen fünf kommen nur in Kommentaren vor: PRICE_INCREASE, RENEWAL_EXTENDED und METADATA_UPDATE in Zeile 73, EXTERNAL_PURCHASE_TOKEN und TEST in Zeile 187.RESCIND_CONSENT,CONSUMPTION_REQUEST,REFUND_DECLINEDundREFUND_REVERSEDliefern im gesamten Repository null Treffer. Der Vollständigkeit halber, was kein Beleg ist:docs/SUBSCRIPTION_GO_LIVE.md:83sagt zwar „set BOTH the Production and Sandbox URL“, doch die Zeile ist eine Runbook-Anweisung unter einer Überschrift, die den Schritt als „needs your re-auth“ markiert, hält also eine Absicht fest und keine abgeschlossene Registrierung; die obige Aussage zur Registrierung stützt sich stattdessen auf die zugestellten Benachrichtigungen. ↩↩↩ -
Apple, Testing Ask to Buy in Xcode, StoreKit. Quelle für Apples Beschreibung des Mechanismus („Mit Ask to Buy sendet das System die Kaufanfrage an die Eltern oder Erziehungsberechtigten, wenn ein Kind einen berechtigten Kauf oder Download tätigen möchte“) und für das Verhalten bei Ablehnung („Ihre App erhält keine Transaktion, weil Sie Ask to Buy abgelehnt haben“). Der Artikel dokumentiert außerdem den Schalter für Ask to Buy unter „Purchase Options“ im Editor für die StoreKit-Konfiguration, und der Transaktionsmanager zeigt die Zustände Pending Ask to Buy, Ask to Buy Approved und Ask to Buy Declined. ↩↩↩
-
Apple, Product.PurchaseResult.pending und Transaction.updates, StoreKit, beide verfügbar ab iOS 15.0. Quelle für die Kurzbeschreibung des Falls („Der Kauf ist ausstehend und erfordert eine Handlung des Kunden“), für den Weg zur Auflösung („Ist ein ausstehender Kauf erfolgreich, stellt StoreKit die resultierende
Transactionin den Transaktions-updateszu“) und für den Zweck der Sequenz („Diese Sequenz empfängt Transaktionen, die außerhalb der App stattfinden, etwa Ask-to-Buy-Transaktionen, das Einlösen von Angebotscodes und Käufe, die Kunden im App Store tätigen“). Das Enum Product.PurchaseResult veröffentlicht drei Fälle:success(_:),pendingunduserCancelled. Apples eigenes Beispiel auf der Enum-Seite kommentiert den ausstehenden Zweig mit „The purchase requires action from the customer. If the transaction completes, it’s available throughTransaction.updates.“ ↩↩ -
Jedes Symbol im obigen Codebeispiel zur Verzweigung wurde am 26. Juli 2026 gegen das JSON von Apples Dokumentation geprüft.
AgeRangeService.sharediststatic let shared: AgeRangeService(iOS 26.0). Die SwiftUI-Environment-Werte sindrequestAgeRange,var requestAgeRange: DeclaredAgeRangeAction { get }(iOS 26.0), undshowSignificantUpdateAcknowledgment,var showSignificantUpdateAcknowledgment: SignificantUpdateAction { get }(iOS 26.4). Die Untergrenze@available(iOS 26.5, *)im Codebeispiel stammt von keinem der beiden:AgeRangeService.AgeRangeDeclaration.confirmedführt iOS 26.5, iPadOS 26.5, Mac Catalyst 26.5 und macOS 26.5, ein Release später als die Bestätigungs-Action, sodass jeder Code, der eine bestätigte erwachsene Person unterscheidet, die höhere Untergrenze erbt. Apples eigenes Beispielprojekt veröffentlicht dieselbe Verfügbarkeit von 26.5.6AgeRangeService.AgeRangelegtlowerBound,upperBound,ageRangeDeclaration, deklariert alsvar ageRangeDeclaration: AgeRangeService.AgeRangeDeclaration?, sowieactiveParentalControlsoffen. Der Vergleich== .confirmedgegen dieses Optional ist zulässig, weilAgeRangeDeclarationlaut seinem Abschnitt zu Beziehungen konform zuEquatableundHashableist. Der Initialisierer vonPermissionButtonlautetinit(question: PermissionQuestion<Topic>, @ViewBuilder label: @escaping () -> Label), in der hier verwendeten Überladung eingeschränkt aufSignificantAppUpdateTopic.26ChangedFeatureViewundAccountVerificationPromptsind Platzhalter für Ihre eigenen Views, keine Apple-Symbole. ↩↩↩ -
Apple, Age ratings values and definitions, Hilfe zu App Store Connect, gelesen am 26. Juli 2026 als bestätigende Quelle dafür, dass die in Anmerkung 9 angekündigten Änderungen vom 18. Juni 2026 in Kraft getreten sind. Unter „Australia age rating values“ führt die Tabelle jetzt zwei Einstufungen, 16+ und R 18+, ohne Zeile für 15+. Ein eigener Abschnitt „Vietnam age rating values“ existiert inzwischen, eingeleitet mit „Wie von Artikel 38 des vietnamesischen Dekrets 147 gefordert“, und seine Zeile 00+ ist definiert als Apps, die „kein anstößiges Material enthalten, aber Fälle der folgenden Inhalte aufweisen können“, aufgezählt werden Kindersicherung, Altersprüfung, nutzergenerierte Inhalte, Messaging und Chat, Werbung sowie seltene Gewinnspiele. Apples Deskriptorliste vom 21. Mai zur australischen Umstellung deckt sich nicht mit der aktuellen Auslöserliste für 16+ auf dieser Seite – eine Abweichung, die ich nicht aufgelöst habe und auf die ich mich nicht stütze, denn die hier gezogene Aussage lautet nur, dass die Stufe 15+ verschwunden ist und die Vietnam-Tabelle existiert. ↩↩↩