ITMS-90870 erscheint beim Upload, obwohl der Startbildschirm im Xcode-Projekt sichtbar ist.

Schnellste Lösung: Wird die App mit dem iOS 27 SDK oder höher gebaut, muss die finale Info.plist im Archive eine gültige, von Apple anerkannte Startbildschirm-Konfiguration enthalten. Korrigieren Sie nicht nur die Projekteinstellungen: Prüfen Sie das fertige .app-Produkt und laden Sie danach ein neues Archive zu TestFlight hoch.

Wer diesen Runbook braucht

Dieser Leitfaden ist für unabhängige Entwickler und kleine Teams gedacht, die eine bestehende iPhone- oder iPad-App mit Xcode 27 testen oder veröffentlichen möchten. Besonders relevant ist er bei SwiftUI-, UIKit- und Cross-Platform-Projekten mit mehreren Targets, automatisch erzeugter Info.plist oder Build-Skripten.

Auch wer Archive und Uploads auf einem remote Mac von MESHLAUNCH ausführt, findet hier die entscheidende Trennung zwischen Quellprojekt und tatsächlich hochgeladenem Binary.

Letzte Aktualisierung: 27.08.2026. Die Angaben wurden anhand von Apple TN3208 zur Startbildschirm-Anforderung, den iOS- und iPadOS-27-Release-Notes, den Xcode-Systemanforderungen und den App-Store-Connect-Release-Notes geprüft. Bei neuen Beta-, RC- oder Produktionsfreigaben muss die Kette erneut validiert werden.

01

Der betroffene Build ist wichtiger als das Deployment Target

Die Serverprüfung richtet sich nach dem SDK, mit dem die App gebaut wurde. Nicht entscheidend ist allein die niedrigste unterstützte iOS-Version. Eine App kann also ein älteres Deployment Target besitzen und trotzdem betroffen sein, wenn das verwendete Build-SDK iOS 27 oder höher ist.

Apple bestätigt für iOS- und iPadOS-Apps, die mit dem iOS 27 SDK oder höher erstellt wurden, die Pflicht zu einer gültigen Startbildschirm-Konfiguration. Fehlt sie im eingereichten Produkt, kann App Store Connect den Upload mit ITMS-90870 ablehnen. Die technische Abgrenzung steht in Apple TN3208.

Für die Planung der Build-Kette gelten damit drei Zustände:

  • Produktionskette mit iOS 26 SDK: Sie kann vorerst bestehen bleiben, sofern sie weiterhin von der aktuellen App-Store-Connect-Kette akzeptiert wird. Das ist aber kein Grund, die Migration aufzuschieben.
  • Xcode 27 Beta-Kette: Sie sollte in einem getrennten Testzweig geprüft werden. Apple hat den Upload von Xcode 27 Beta 5 zu TestFlight bestätigt. Das ist nicht gleichbedeutend mit einer Bestätigung für eine produktive App-Store-Veröffentlichung.
  • Spätere Produktionsumstellung: Apple hat in den hier geprüften Quellen noch keinen verbindlichen Termin genannt, ab dem produktive App-Store-Builds zwingend mit dem iOS 27 SDK angenommen werden. Eine unbestätigte Terminprognose gehört deshalb nicht in den Release-Plan.

Die relevante Entscheidung lautet nicht „Deployment Target erhöhen oder nicht“. Sie lautet: „Mit welchem SDK wurde das eingereichte Archive gebaut, und welche Konfiguration liegt danach wirklich im App-Bundle?“

Achtung: Ein grünes Debug-Run und eine korrekte Einstellung im Projekteditor beweisen nicht, dass die Release-Info.plist unverändert im Archive landet. Build Configuration, Target und Skripte können unterschiedliche Werte erzeugen.

02

Erste Messgröße: Ist die Startbildschirm-Deklaration vollständig?

Für die Validierung genügt kein leerer Schlüssel. Die Konfiguration muss auf eine tatsächlich verwendbare Startbildschirm-Definition oder eine vorhandene Storyboard-Ressource verweisen. Apple beschreibt die möglichen Einträge in der Dokumentation zu UILaunchScreen und in der Anleitung zum Spezifizieren des Startbildschirms.

Wir prüfen zuerst, welcher Ansatz zum Projekt passt:

  • UILaunchScreen: Geeignet, wenn der Startbildschirm deklarativ über die Info.plist beziehungsweise die zugehörigen Build-Einstellungen beschrieben wird.
  • LaunchScreen.storyboard: Sinnvoll für ältere UIKit-Projekte oder Projekte, die bereits ein Startbildschirm-Storyboard als Release-Ressource verwenden.
  • Mehrere Startbildschirm-Szenarien: Nur dann getrennt konfigurieren, wenn die App tatsächlich unterschiedliche Ressourcen oder Größenvarianten benötigt. Jede Referenz muss auf eine vorhandene und korrekt eingebundene Ressource zeigen.
  • Leere oder erfundene Werte: Nicht verwenden. Ein leerer UILaunchScreen-Eintrag, ein falscher Storyboard-Name oder eine Datei, die nicht im Bundle liegt, beseitigt die Ursache nicht zuverlässig.

Die Entscheidung sollte anhand des finalen Produkts getroffen werden. Wenn das Projekt bereits ein gültiges LaunchScreen.storyboard besitzt und dieses in der Release-Konfiguration eingebunden ist, ist eine unnötige Umstellung auf eine zweite Methode riskanter als eine saubere Prüfung. Bei einem neuen SwiftUI-Projekt kann eine deklarative Konfiguration besser zum aktuellen Aufbau passen. Ausschlaggebend sind aber immer die unterstützte Konfiguration und das resultierende Bundle.

03

Zweite Messgröße: Welches Target erzeugt die eingereichte Info.plist?

SwiftUI: automatische Generierung nicht mit automatischer Korrektheit verwechseln

Bei SwiftUI-Projekten wird die Info.plist häufig aus Target-Informationen und Build-Einstellungen erzeugt. Dadurch kann im Quellbaum keine offensichtliche, von Hand gepflegte Datei liegen. Trotzdem muss das erzeugte Produkt einen gültigen Startbildschirm-Eintrag enthalten.

Prüfen Sie den tatsächlich verwendeten App Target. Ein Widget, eine Share Extension oder ein internes Test-Target kann eigene Einstellungen besitzen, ist aber nicht automatisch das Bundle, das App Store Connect erhält. Relevant ist die Haupt-App im Release-Archive.

UIKit: Datei, Target und Ressource gemeinsam prüfen

Bei UIKit-Projekten liegt die Konfiguration oft in einer manuell verwalteten Info.plist. Der Dateiname allein reicht nicht als Nachweis. Entscheidend sind:

  • die Zuordnung der Datei zum richtigen Target,
  • die verwendete Release-Konfiguration,
  • die Einbindung des Storyboards oder anderer Startbildschirm-Ressourcen,
  • die Werte nach der Build- und Copy-Phase.

Die Build-Settings-Referenz von Apple hilft dabei, Variablen und Konfigurationswerte nachzuvollziehen. Bei unterschiedlichen Schemes darf nicht angenommen werden, dass die Debug-Einstellungen automatisch für Release gelten.

Cross-Platform-Projekte: Generatoren als mögliche Überschreiber

Cross-Platform-Frameworks erzeugen oder verändern iOS-Projektdateien häufig während eines Build-Schritts. Ein manueller Fix im Xcode-Projekt kann beim nächsten Generieren verschwinden. Prüfen Sie deshalb zusätzlich:

  1. die deklarative Projektquelle des Frameworks,
  2. den generierten iOS-Unterordner,
  3. nachgelagerte Build-Skripte,
  4. die Werte im finalen Release-Archive.

Bei mehreren Targets und Konfigurationen empfiehlt sich eine kleine Matrix im internen Release-Protokoll: App Target, Scheme, Configuration, erwarteter Startbildschirm-Eintrag und Ergebnis im Archive. Das verhindert, dass nur das lokale Standard-Scheme repariert wird.

04

Dritte Messgröße: Stimmen Quellprojekt und Archive überein?

Der häufigste Denkfehler bei ITMS-90870 ist die Prüfung an der falschen Stelle. Die Datei im Projekt ist ein Ausgangspunkt. Der Server erhält jedoch das signierte und archivierte App-Bundle.

Schritt für Schritt zum belastbaren Archive-Nachweis

  1. SDK und Xcode festhalten
    Notieren Sie die verwendete Xcode-Version, das Build-SDK, Scheme und die Release-Konfiguration. Für die Xcode-27-Testkette sollte dieser Eintrag eindeutig als Beta-Umgebung gekennzeichnet sein.

  2. App Target auswählen
    Öffnen Sie die Target-Einstellungen und prüfen Sie, welches Target tatsächlich archiviert wird. Kontrollieren Sie außerdem, ob das Scheme auf eine andere Configuration als erwartet zeigt.

  3. Startbildschirm konfigurieren
    Verwenden Sie eine gültige UILaunchScreen-Konfiguration oder ein korrekt eingebundenes LaunchScreen.storyboard. Prüfen Sie Namen, Pfade und Target Membership. Entfernen Sie leere Schlüssel und veraltete Referenzen.

  4. Release Archive erzeugen
    Verwenden Sie den produktionsnahen Archive-Einstieg und nicht nur einen lokalen Run. Bei automatisierten Builds müssen dieselben Export- und Signing-Einstellungen wie in der vorgesehenen Upload-Kette verwendet werden.

  5. Finale Info.plist auslesen
    Untersuchen Sie die Info.plist innerhalb des .app-Bundles im Archive. Vergleichen Sie den tatsächlichen Eintrag mit der Projektquelle. Ein Unterschied ist ein Beweis dafür, dass Build Settings, Generator oder Skript eingegriffen hat.

  6. Ressourcen im Bundle kontrollieren
    Bei einer Storyboard-Lösung muss die referenzierte Ressource im fertigen Bundle vorhanden sein. Bei einer deklarativen Lösung müssen die verwendeten Werte syntaktisch und semantisch gültig sein. Eine bloße Zeichenkette in der Info.plist genügt nicht, wenn die zugehörige Datei fehlt.

  7. Ergebnis dokumentieren
    Sichern Sie ein anonymisiertes Fragment der Build-Einstellungen, den relevanten Archive-Pfad, die geprüften Schlüssel und den Upload-Status. Entfernen Sie Bundle IDs, Kontonamen, Zertifikatsdaten und interne Pfade aus allen Belegen.

  8. Neues Archive zu TestFlight laden
    Laden Sie nicht das alte, möglicherweise zwischengespeicherte Produkt erneut hoch. Ein neues Archive zeigt, ob die Änderung tatsächlich in das Binary gelangt ist. Die offiziellen Schritte zum Hochladen eines App-Builds und die möglichen Build-Statuswerte sollten zum Protokoll gehören.

  9. Produktionsfreigabe getrennt bestätigen
    Ein erfolgreicher TestFlight-Upload bestätigt die Testkette. Er ersetzt nicht die Prüfung, ob die gewählte Xcode- und SDK-Kombination für eine produktive App-Store-Einreichung freigegeben ist.

Die kompakte Abnahme-Checkliste

  • [ ] Das verwendete Build-SDK ist dokumentiert.
  • [ ] Das Deployment Target wurde nicht fälschlich als alleinige Entscheidungsgrundlage verwendet.
  • [ ] Das tatsächlich archivierte App Target ist bekannt.
  • [ ] Scheme und Release Configuration sind festgehalten.
  • [ ] UILaunchScreen oder LaunchScreen.storyboard ist gültig gewählt.
  • [ ] Keine leeren Schlüssel und keine erfundenen Ressourcennamen sind enthalten.
  • [ ] Die Ressource liegt im finalen .app-Bundle.
  • [ ] Die Info.plist im Archive wurde direkt geprüft.
  • [ ] Generatoren und Build-Skripte wurden auf Überschreiben untersucht.
  • [ ] Die App wurde mit genau diesem neuen Archive zu TestFlight geladen.
  • [ ] Upload-Status und relevante Fehlermeldung wurden anonymisiert protokolliert.
  • [ ] Für die Produktion existiert eine dokumentierte Xcode-Version und ein Rückfallweg.
05

Vierte Messgröße: Zeigt der erste Start den richtigen Inhalt?

Die Serverprüfung und die sichtbare Darstellung sind zwei verschiedene Abnahmen. Eine App kann den Upload akzeptieren und auf einem Gerät trotzdem einen falschen oder veralteten Startbildschirm anzeigen. Umgekehrt kann ein lokaler Start korrekt aussehen, während das Archive die Konfiguration nicht enthält.

Apple empfiehlt, die alte Installation zu entfernen und die App anschließend neu zu starten. Dadurch wird ein Cache als Fehlerursache ausgeschlossen. Prüfen Sie dabei:

  • erscheint ein leerer oder schwarzer Bildschirm,
  • wird ein altes Bild angezeigt,
  • ist ein Logo abgeschnitten,
  • liegt der Inhalt außerhalb der sicheren Fläche,
  • unterscheiden sich iPhone- und iPad-Darstellung,
  • ist die Storyboard-Ressource tatsächlich die erwartete Version.

Der Simulator eignet sich für eine schnelle Sichtprüfung verschiedener Gerätegrößen. Vor einer produktiven Veröffentlichung sollte zusätzlich ein physisches Gerät verwendet werden. Aus einer subjektiv schnellen oder langsamen Anzeige darf ohne eigene Messung keine Startgeschwindigkeitsangabe abgeleitet werden.

Wenn nur die alte Installation den falschen Bildschirm zeigt, ist das zunächst ein Hinweis auf Cache- oder Installationszustände. Wenn eine frisch installierte Archive-Version weiterhin falsch startet, muss die Ressourcen- und Layoutprüfung zurück in den Release-Schritt.

Erfahrung aus der Abnahme: „Im Simulator sieht es richtig aus“ beantwortet nur die Anzeige-Frage. Für ITMS-90870 bleibt die Archive-Info.plist die maßgebliche Prüfstelle.

06

Fünfte Messgröße: Reproduzierbarkeit der Upload-Umgebung

Eine lokale Korrektur kann auf dem Build-Rechner wirkungslos bleiben, wenn der eigentliche Upload über eine andere Umgebung läuft. Das betrifft insbesondere wechselnde Xcode-Versionen, getrennte Schemes, automatisch generierte Projektdateien und Skripte, die vor dem Archive erneut Werte setzen.

Für eine remote oder automatisierte Kette sollten wir denselben Ablauf wie in der Produktion nachstellen:

  • identische Xcode-Installation,
  • identisches Scheme,
  • identische Release Configuration,
  • identischer Archive-Einstieg,
  • identische Generator- und Skriptversionen,
  • identische Prüfung der finalen Info.plist,
  • separater TestFlight-Upload mit dem neuen Produkt.

Eine gemietete Mac-Umgebung ist dabei kein Ersatz für die technische Abnahme. Sie ist ein unabhängiger, sauber rücksetzbarer Ort, an dem sich prüfen lässt, ob das Projekt außerhalb des lokalen Entwicklerrechners dasselbe Archive erzeugt. Für Teams mit knappem Hardwarebudget kann MESHLAUNCH für remote Mac-Arbeitsplätze eine kurzfristige Testumgebung bereitstellen. Wer dagegen dauerhaft eine eigene Maschine benötigt, sollte die Anschaffung eines Mac mini für die lokale Build-Kette gegen Wartung, Xcode-Kompatibilität und Ausfallrisiko abwägen.

Wichtig ist die Beweiskette: Quellprojekt, erzeugte Build-Einstellungen, finale Archive-Info.plist, Starttest und TestFlight-Status müssen demselben Build zugeordnet sein. Nur dann lässt sich der Fehler reproduzierbar schließen.

07

Produktionsentscheidung nach der Abnahme

Wenn die aktuelle Produktionskette noch mit dem iOS 26 SDK baut und keinen ITMS-90870-Fehler auslöst, muss nicht am Tag einer Veröffentlichung gleichzeitig die Startbildschirm-Migration und ein Xcode-Wechsel durchgeführt werden. Die bestehende Kette kann vorläufig als Rückfallweg dienen.

Die Migration in einen Xcode-27-Testzweig sollte trotzdem sofort erfolgen. Dabei wird nicht nur der Startbildschirm repariert. Wir prüfen auch, ob Generatoren, Signing, Archive-Export und TestFlight-Upload in der neuen Umgebung zusammenpassen. Der Produktionswechsel erfolgt erst, wenn diese Abnahme dokumentiert ist und Apple die relevante Annahme für den vorgesehenen Veröffentlichungsweg bestätigt.

Ein sinnvoller Release-Entscheid lautet:

  • Noch kein iOS-27-SDK im Produktionsbuild: aktuelle Kette stabil halten, Xcode-27-Testzweig parallel aufbauen.
  • iOS-27-SDK im Testbuild: Info.plist, Archive und TestFlight vollständig prüfen.
  • ITMS-90870 trotz Projektänderung: finale Bundle-Datei untersuchen, nicht zuerst DerivedData löschen oder Xcode neu installieren.
  • Archive korrekt, Upload weiterhin abgelehnt: Build-Status, SDK-Unterstützung und App-Store-Connect-Hinweise getrennt prüfen.
  • Keine reproduzierbare Abnahme auf dem bisherigen Rechner: unabhängige Mac-Umgebung für den Test verwenden und einen klaren Rückfall auf die bisherige Produktionskette dokumentieren.
08

Häufige Fragen zur Startbildschirm-Prüfung

Die folgenden Antworten trennen bewusst die fünf Stellen, an denen ein Fehler entstehen kann: SDK, Target, Info.plist, Archive und Upload. Dadurch wird die Fehlersuche kürzer als ein pauschales Neuinstallieren der Entwicklungsumgebung.

09

Fazit: Erst das Archive, dann die Einreichung

Ein fehlender iOS-27-Startbildschirm ist kein reines Interface-Problem. Bei einem Build mit iOS 27 SDK oder höher zählt die gültige Deklaration im finalen App-Bundle. Die sichere Reihenfolge lautet: Target und SDK feststellen, Info.plist korrigieren, Release Archive prüfen, frisch installieren, zu TestFlight hochladen und erst danach die Produktionsfreigabe bewerten.

Wenn die bisherige Lösung auf einem lokalen Mac beruht, entstehen dabei drei reale Schwachstellen: Die Maschine kann die benötigte Xcode-Version nicht parallel installieren, lokale Build-Einstellungen können vom automatisierten Archive abweichen, und ein einzelner Rechner bietet keinen sauberen Rückfall für die Migration. Für eine kurzfristige Kompatibilitätsprüfung ist deshalb ein unabhängiger Mac bei MESHLAUNCH oft die kontrollierbarere Ergänzung. Das ersetzt keine dauerhafte Produktionsmaschine, kann aber ein neues Xcode-27-Archive und den TestFlight-Nachweis ermöglichen, ohne den bestehenden Release-Rechner sofort auszutauschen.