iOS-vCard-Exporte auf dem Cloud-Mac prüfen: Felder und Rücklesen

iOS-vCard-Exporte auf dem Cloud-Mac prüfen: Felder und Rücklesen

Sie exportieren Kundenkontakte als .vcf: Das Teilen-Menü lässt sich öffnen, doch nach dem Import ist nur noch eine Rufnummer vorhanden, und das Semikolon im Namen steht an der falschen Stelle. Solche Fehler lassen sich nicht anhand von Screenshots abnehmen. Prüfen Sie auf einem Cloud-Mac zuerst den Ablauf „Daten erzeugen → erneut einlesen → Felder einzeln vergleichen“ und testen Sie erst danach das Teilen und Importieren unter iOS. So trennen Sie Formatfehler von Problemen der Benutzeroberfläche.

Zuerst festlegen, welche Daten erhalten bleiben müssen

Dieser Artikel prüft die Umwandlung des anwendungsinternen Datenmodells in vCard, ohne das echte Adressbuch auszulesen. Verwenden Sie synthetische Kontakte mit chinesischen Zeichen, Akzentzeichen, mehreren Rufnummern und benutzerdefinierten Labels. So gelangen keine personenbezogenen Daten in die Build-Protokolle.

Für die erste Fassung genügt ein kleiner Prüfvertrag: Nachname und Vorname müssen unverändert zurückkommen; Rufnummern müssen als ursprüngliche Eingabezeichenfolgen erhalten bleiben; die Zuordnung zwischen benutzerdefinierten Labels und Rufnummern darf sich nicht ändern; leere Felder dürfen nicht ungefragt anwendungsspezifische Standardwerte erhalten. Die Normalisierung von Rufnummern gehört in eine separate Logik. Entfernen Sie nicht nebenbei beim Export das führende Pluszeichen.

Lässt sich eine Datei einlesen, ist damit nur ihre syntaktische Gültigkeit belegt. Erst übereinstimmende Felder nach dem Rücklesen zeigen, dass auf diesem Konvertierungsweg keine für Sie relevanten Daten verloren gegangen sind.

Lassen Sie Kontaktbilder, Notizen und Gruppen zunächst außen vor. Für sie gelten andere Grenzen hinsichtlich Datenmenge, Zugriff und Kompatibilität. Erweitern Sie die Testdaten dafür separat, statt bei einem einzigen Fehler gleich alle Felder untersuchen zu müssen.

Mit dem Systemserialisierer eine Referenz erstellen

Speichern Sie den folgenden Code auf einem Cloud-Mac mit installierten Xcode-Kommandozeilentools als vcard-check.swift. Er verwendet ausschließlich Foundation und Contacts, ruft keine APIs zum Abfragen des Adressbuchs auf und benötigt keine Zugriffsberechtigung für Kontakte.

import Foundation
import Contacts

struct CheckFailure: Error {
    let field: String
}

func require(_ condition: Bool, _ field: String) throws {
    if !condition {
        throw CheckFailure(field: field)
    }
}

func phones(_ contact: CNContact) -> [String: String] {
    var result: [String: String] = [:]
    for item in contact.phoneNumbers {
        result[item.label ?? ""] = item.value.stringValue
    }
    return result
}

do {
    let source = CNMutableContact()
    source.familyName = "林;测试"
    source.givenName = "Zoë,研发"
    source.phoneNumbers = [
        CNLabeledValue(
            label: "build-primary",
            value: CNPhoneNumber(stringValue: "+12025550101")
        ),
        CNLabeledValue(
            label: "build-secondary",
            value: CNPhoneNumber(stringValue: "+12025550102")
        )
    ]

    let data = try CNContactVCardSerialization.data(with: [source])
    try data.write(to: URL(fileURLWithPath: "contact.vcf"),
                   options: .atomic)

    let contacts = try CNContactVCardSerialization.contacts(with: data)
    try require(contacts.count == 1, "contact-count")
    let restored = contacts[0]
    try require(restored.familyName == source.familyName, "family-name")
    try require(restored.givenName == source.givenName, "given-name")
    try require(restored.phoneNumbers.count == 2, "phone-count")
    try require(phones(restored) == phones(source), "phone-values")
} catch {
    FileHandle.standardError.write(Data("vCard check failed\n".utf8))
    exit(1)
}

Prüfen Sie nach der Ausführung den Exitcode des Prozesses, statt nach einer Erfolgsmeldung zu suchen:

mkdir -p artifacts/vcard
cd artifacts/vcard
xcrun swift ../../vcard-check.swift

Das Beispiel setzt voraus, dass das Skript im Stammverzeichnis des Repositorys liegt. Setzen Sie die Pipeline nur fort, wenn der Befehl den Exitcode null zurückgibt; stoppen Sie bei einem Fehler die nachfolgenden Auslieferungsschritte. In einem echten Projekt gehören die Assertions in ein Test-Target, damit der Bericht das konkret betroffene Feld ausweist. Geben Sie die Kontaktinhalte nicht direkt im Protokoll aus.

Sonderzeichen in eigenen Testfällen prüfen

Komma und Semikolon im Beispiel sind bewusst gewählt. Sie haben innerhalb der vCard-Struktur eine Bedeutung. Wer Texte einfach zusammensetzt, kann dadurch einen Namen versehentlich in mehrere Komponenten zerlegen. Erstellen Sie die Referenz mit dem Systemserialisierer, statt zunächst eigene Ersetzungsregeln zu schreiben und anschließend deren Richtigkeit zu bestätigen.

Ergänzen Sie drei weitere Eingabesätze: einen Namen mit Backslash, einen Firmennamen mit Zeilenumbruch und eine ausreichend lange Zeichenfolge mit Mehrbytezeichen. Variieren Sie pro Satz nur eine Eigenschaft, lesen Sie das entsprechende Attribut zurück und prüfen Sie, dass die Gesamtzahl der Kontakte weiterhin eins beträgt. So erkennen Sie, wenn ein Zeilenumbruch fälschlich als zusätzliche Eigenschaft oder als weiterer Datensatz behandelt wird.

Zeilenlänge ist nicht gleich Zeichenanzahl

Physische Zeilen in vCard können gefaltet werden; außerdem haben chinesische Zeichen eine andere Länge in Bytes. Implementieren Sie die Zeilenfaltung nicht, indem Sie „nach einer festen Anzahl von Swift-Zeichen einen Zeilenumbruch einfügen“. Schreiben Sie erst recht keinen eigenen Parser auf Basis eines zeilenweisen split. Wenn Sie einen eigenen Encoder pflegen, prüfen Sie die Regeln auf Byte-Ebene für die von ihm ausdrücklich unterstützte vCard-Version und lassen Sie seine Ausgabe von Contacts zurücklesen.

Im Beispiel dienen die Labels als Schlüssel eines Dictionarys. Das eignet sich nur für Testdaten mit eindeutigen Labels. Reale Kontakte können dasselbe Label mehrfach verwenden. Vergleichen Sie beim Ausbau der Tests stattdessen Multimengen aus Paaren von „Label und Rufnummer“, damit auch die Anzahl identischer Einträge erhalten bleibt.

Semantische Gleichheit von Dateigleichheit unterscheiden

Wird derselbe Kontakt erneut serialisiert, können sich die Reihenfolge der Eigenschaften und die Zeilenfaltung ändern. Ein direkter Vergleich mit einem Datei-Snapshot ist deshalb nicht immer geeignet. Vergleichen Sie vorrangig die eingelesenen Felder. Verwenden Sie Datei-Hashes zur Prüfung der Übertragungsintegrität, nicht zur Beurteilung der semantischen Gleichheit von Kontakten.

Ergänzen Sie für den Sammelexport Testfälle mit einem leeren Array, einem einzelnen Kontakt und mehreren Kontakten. Identifizieren Sie jeden Datensatz über einen eindeutigen, eigens für den Test vergebenen Namen, nicht über die Reihenfolge im eingelesenen Array. Prüfen Sie die Anzahl der Datensätze, die Feldwerte und die Anzahl der Einträge in mehrwertigen Feldern getrennt. So verhindern Sie, dass das Überschreiben von Dictionary-Einträgen Datenverluste verdeckt.

Auch wenn das Systemframework seine eigene Ausgabe erfolgreich zurückliest, ist damit die vollständige Interoperabilität zwischen Anwendungen noch nicht belegt. Sind die Dateien auch für andere Importprogramme bestimmt, bewahren Sie denselben Satz synthetischer Dateien auf und prüfen Sie ihn mit jedem dieser Programme. Für die Umwandlung nicht unterstützter Labels braucht es klare Vereinbarungen; sie dürfen nicht stillschweigend ignoriert werden.

In die Pipeline einbinden und die iOS-Abnahme ergänzen

Führen Sie die schnelle Formatprüfung nach Änderungen an der Teilen-Funktion aus und protokollieren Sie die Versionen von Betriebssystem und Toolchain. Archivieren Sie bei einem Fehler ausschließlich die synthetische .vcf und die Fehlerkennungen der betroffenen Felder. Bereinigen Sie das Verzeichnis nach erfolgreicher Prüfung gemäß den Aufbewahrungsregeln der Pipeline. Verwenden Sie kein echtes Adressbuch als Test-Fixture.

Prüfen Sie unter iOS außerdem die Dateiendung, den vom Freigabeelement bereitgestellten Datentyp und den Dateiinhalt, den die Zielanwendung tatsächlich erhält. Kontrollieren Sie nach dem Import in eine separate Testumgebung beide Rufnummern, die benutzerdefinierten Labels und die Sonderzeichen. Löschen Sie anschließend die Testeinträge. Ergebnisse im Simulator ersetzen nicht die Bestätigung auf dem Zielgerät und in der vorgesehenen Importanwendung.

Halten Sie abschließend drei voneinander unabhängige Ergebnisse fest: Die erzeugten Daten lassen sich einlesen, die Kernfelder lassen sich unverändert zurücklesen, und die geteilte Datei wird von der Zielanwendung korrekt importiert. Scheitert eine Prüfung, suchen Sie auf der zugehörigen Ebene nach der Ursache. Entfernen Sie keine Sonderzeichen und beschränken Sie sich nicht auf die erste Rufnummer, nur damit der Test scheinbar besteht.

Häufig gestellte Fragen

Braucht der Test Zugriff auf das Adressbuch?

Nein. Er erzeugt Kontakte im Speicher und serialisiert Daten. Systemkontakte werden weder gelesen noch gespeichert.

Warum werden die Dateien nicht byteweise verglichen?

Die Reihenfolge der Eigenschaften und Zeilenumbrüche können sich ändern. Zuerst werden die Dateien geparst und die fachlichen Feldwerte verglichen.

Den nächsten Build auf einer Cloud-Mac-Workstation ausführen

Ein ganzer Mac mini exklusiv für Sie – keine virtuelle Maschine. Wählen Sie die Laufzeit passend zu Ihrem Vorhaben. Ob die Workstation verfügbar ist, sehen Sie in Echtzeit in der Konsole.

Cloud-Mac jetzt mieten

Erst die Konfiguration prüfen, dann loslegen

Informieren Sie sich über Abrechnungszeiträume und Zusatzoptionen für Desk M4 oder richten Sie Ihre erste Verbindung mit der Einrichtungsanleitung ein.