Es ist allgemein anerkannt, dass Wallet nicht der beliebteste Dienst in der GUS ist. Aber bereits im zweiten Projekt in Folge stellt der Kunde die Aufgabe "Integration mit Wallet vornehmen". Aus diesem Grund habe ich beschlossen, diesen Artikel zu schreiben, um über den gesamten Service zu sprechen und zu zeigen, wie ich mein Produkt in ihn integrieren kann.
Was ist eine Brieftasche? Sie können verschiedene Arten von Karten in Ihrem Telefon behalten (Tickets, Rabattkarten usw.), was den Benutzern des Produkts das Leben erleichtert. Darüber hinaus ist es möglich, Informationen über die Karte durch Push-Benachrichtigungen zu aktualisieren. Dies ist jedoch ein Thema für einen separaten Artikel. Wenn Sie jedoch eine Karte / ein Ticket / ein Abonnement haben, die bzw. das in das Telefon integriert werden kann, gibt es eine Lösung! Wie es geht - lesen Sie unten.
In der Regel ist Ihr Server für die Erstellung der Karte verantwortlich. Die Anwendung empfängt die Karte in Form einer .pkpass-Datei und über die Anwendung kann der Benutzer die Karte zu Wallet hinzufügen.
Kartenstruktur
Was ist die Karte aus Sicht des Entwicklers? Eine Karte ist ein Archiv mit der Erweiterung .pkpass. Es enthält alle Daten, die für die Anzeige und den Betrieb der Karte erforderlich sind. Der Inhalt des Archivs ist in der folgenden Tabelle aufgeführt.
Datei | Termin |
---|
background.png | Hintergrundbild für die Karte. |
footer.png | Bild neben dem Barcode |
icon.png | Symbol für Benachrichtigungen und Briefe |
logo.png | Kartenlogo. Oben links angezeigt |
manifest.json | Registrierung aller enthaltenen Dateien |
Unterschrift | PKCS7-Signatur |
pass.json | Aussehen und Karteninformationen |
strip.png | Bild befindet sich hinter der Hauptbeschreibung der Karte |
thumbnail.png | Zusätzliches Bild (bitte angeben) |
Folgende Kartentypen stehen zur Verfügung:
- Bordkarte: mit dem Flugzeug oder dem Zug. Normalerweise gilt der Gutschein für eine Reise.
- Gutschein: für Gutscheine und Sonderangebote;
- Veranstaltungsticket: Kann sowohl für eine Veranstaltung als auch für eine ganze Saison verwendet werden.
- Rabattkarte: Kundenkarten, Rabatt- oder Geschenkkarten;
- Übersichtskarte: Wenn für Ihren Fall keine der oben genannten Punkte zutrifft: Zum Beispiel eine Karte für die Fahrt mit der U-Bahn oder ein Pass für das Fitnessstudio.
Betrachten Sie schematisch das Erscheinungsbild verschiedener Karten. Bilder werden am besten wie in der obigen Tabelle angegeben benannt.
Bordkarte

Gutschein

Veranstaltungsticket

Gemeinschaftskarte

Rabattkarte

Pass.json-Struktur
Erforderliche Felder. Enthält Pass-Typ-ID, Team-ID, Organisationsname usw.
Schlüssel für verwandte Anwendungen. Wird benötigt, um Anwendungen anzuzeigen, die der Karte "zugeordnet" werden müssen.
Schlüssel "Ablaufdatum" Karten.
Schlüssel von Relevanz. Zum Beispiel die Koordinaten des Bereichs, in dem die Karte verwendet werden kann, oder der Beginn des Ereignisses, für das sie bestimmt ist.
Der Schlüssel ist Stil. Zu Beginn des Artikels wurden 5 Arten von Karten für Wallet aufgelistet. Jeder von ihnen hat seinen eigenen Stil. Ein solcher Schlüssel muss unbedingt einer sein.
Schlüssel für die visuelle Gestaltung der Karte. Zusätzlich zum Offensichtlichen enthalten sie Informationen über den auf der Karte angezeigten Barcode.
Webdienstschlüssel. Sie können Webdienste verwenden, um mit der Karte zu interagieren, und sie beispielsweise automatisch aktualisieren.
NFC-Schlüssel. Enthalten zusätzliche Informationen für Apple Pay-Transaktionen.
Nun zu allem im Detail.
Erforderliche Felder
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
Beschreibung | String Lokalisiert | Eine kurze Beschreibung der Karte. Lokalisiert. |
formatVersion | Int | Dateiformatversion. Der Wert muss 1 sein. |
organisationsname | String Lokalisiert | Der Name der Organisation, die die Karten ausstellt. |
passTypeIdentifier | String | Pass Type ID und Entwicklerkonto. |
Seriennummer | String | Seriennummer einer einzelnen Karte |
teamIdentifier | String | Team ID des Entwicklungsteams |
Schlüssel für verwandte Anwendungen
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
AssociatedStoreIdentifiers | [Int] | Optional. Die ID der mit der Karte verknüpften Anwendungen. Der erste, der mit dem aktuellen Gerät kompatibel ist, wird immer verwendet. |
appLaunchURL | String | URL, die beim Öffnen an die Anwendung übergeben wird |
Stilschlüssel
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
Primärfelder | [JSON] | Grundlegende Informationen zur Karte. |
sekundäre Felder | [JSON] | Hintergrundinformationen. |
Hilfsfelder | [JSON] | Felder für zusätzliche Informationen. Optional |
headerFields | [JSON] | Der Titel der Karte. Es wird auch dann angezeigt, wenn die Karten in der Liste sichtbar sind. |
Hilfsfelder | [JSON] | Grundlegende Informationen zur Karte. |
transitType | String | Art des Transports für Ticketkarten. Es kann folgende Werte annehmen: PKTransitTypeAir, PKTransitTypeBoat, PKTransitTypeBu`, PKTransitTypeGeneric, `PKTransitTypeTrain`. |
backFields | [JSON] | Array von Feldern, die für die Rückseite der Karte verantwortlich sind |
JSON hat in diesem Fall die folgende Form:
"key" : "value1", "label" : "value2", "value" : "value3"
Der Wert durch den Werteschlüssel kann entweder numerisch oder als Zeichenfolge sein. CurrencyCode zusammen mit dem Zeichenfolgenwert kann jedoch nicht verwendet werden. Bei AuxiliaryFields und SecondaryFields kann es mehrere geben, und Sie sollten die Länge der in ihnen verwendeten Zeilen überwachen.
Schlüssel für visuelles Design
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
Barcodes | [JSON] | Informationen zum Barcode (siehe unten). |
Hintergrundfarbe | Farbe als Schnur | Hintergrundfarbe (# Fa32e4) |
Vordergrundfarbe | Farbe als Schnur | Beschriften Sie die Farbe mit Werten |
groupingIdentifier | String | Optional für Veranstaltungstickets und Transporttickets. Karten mit demselben Stil - passTypeIdentifier und groupingIdentifier - werden gruppiert |
labelColor | Farbe als Schnur | Beschriften Sie Text mit Feldnamen |
logoText | Lokalisierbare Zeichenfolge | Text neben dem Logo angezeigt |
Barcode
Der wichtigste Teil der Karte. Darin ist eine Kartenidentifikationsnummer eingenäht (z. B. eine physische Kartennummer oder eine Ticketnummer). Es ist wichtig, dass der Scanner oder ein anderes Tool Codes in der richtigen Codierung lesen kann.
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
altText | String | Optionaler Text wird neben dem Barcode angezeigt, wenn der Barcode nicht gelesen wird. |
Format | String | Barcode-Format. Kann Werte annehmen: PKBarcodeFormatQR, PKBarcodeFormatPDF417, PKBarcodeFormatAztec, PKBarcodeFormatCode128 |
Nachricht | String | Code oder Kartennummer in Barcode verschlüsselt. |
messageEncoding | String | Nachrichtenkodierung. Normalerweise iso-8859-1 |
Lage
Diese Schlüssel sind für den Ort verantwortlich, an dem die Karte verwendet werden kann.
Geben Sie JSON ein | Datentyp | Beschreibung |
---|
Altiture | String | Optionaler Text wird neben dem Barcode angezeigt, wenn der Barcode nicht gelesen wird. |
Breitengrad | Längengrad | Breitengrad |
Länge | Doppel | Breitengrad |
relevanterText | String | Optionaler Text, der auf dem Sperrbildschirm angezeigt wird, wenn der Benutzer den Bereich der Karte betritt. |
Rückseite
Zusätzliche Informationen können im umgekehrten Informationsteil platziert werden: Nutzungsbedingungen, Richtlinien für die automatische Aktualisierung, Kontaktdaten und ein Link zu der Anwendung, zu der die Karte gehört. Die Abbildung zeigt die Entsprechung der Felder in pass.json und das Erscheinungsbild der Rückseite der Karte. Wenn sich im Wertefeld Links, Telefonnummern usw. befinden, werden diese automatisch hervorgehoben.

Erstellen Sie eine Karte. Teil 2
Also, die Bilder sind fertig, pass.json wird gebildet, es bleibt alles zusammen zu setzen. Füllen Sie dazu manifest.json aus (siehe Tabelle 1), wo Sie alle Bilder und pass.json einfügen müssen. Es stellt sich so etwas heraus:
. . . . . . "pass.json" = 303c753abc39aa732ec74643d6db28348fe8a823; "strip.png" = 736d01f84cb73d06e8a9932e43076d68f19461ff; "strip@2x.png" = 468fa7bc93e6b55342b56fda09bdce7c829d7d46; . . . . . .
Ab diesem Zeitpunkt muss nichts mehr geändert werden, da der SHA nicht korrekt ist. Im Falle von Änderungen muss der SHA neu generiert werden.
Als Nächstes müssen Sie im Büro des Entwicklers eine Pass-Typ-ID erstellen und ein Zertifikat dafür erstellen. Die Vorgehensweise sollte mehr oder weniger vertraut sein, wenn Sie zuvor beispielsweise Bereitstellungsprofile erstellt haben.

Wechseln Sie als Nächstes zum Schlüsselbund und exportieren Sie von dort das Apple Worldwide Developer Relation Certificate (WWDR) als .pem.

Von dort exportieren wir die erstellte Pass Type ID als .p12. Zu diesem Zeitpunkt werden Sie von der Haushälterin aufgefordert, das Passwort für das Zertifikat einzugeben. In diesem Fall ist ein Passwort optional.
Bitte beachten Sie, dass alle weiteren Aktionen in einem Ordner ausgeführt werden müssen, in dem manifest.json, pass.json und images bereits liegen sollten.
Jetzt müssen Sie eine Signatur generieren, mit der wir das Archiv signieren. Exportieren Sie zunächst die Pass Type ID und den Schlüssel dazu als .pem.
openssl pkcs12 -in certificate.p12 -clcerts -nokeys -out passcertificate.pem -passin pass: your_password
und
openssl pkcs12 -in certificates.p12 -nocerts -out passkey.pem -passin pass: -passout pass:new_password
Jetzt können wir eine Signatur erstellen. Machen wir es zu einem Befehl:
openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:___
Also, alles ist bereit für uns, es bleibt nur das Archiv zu sammeln, wir tun dies mit dem Befehl:
zip -r nameOfPass.pkpass manifest.json pass.json signature logo.png logo@2x.png logo@3x.png icon.png icon@2x.png icon@3x.png
Ich mache Sie darauf aufmerksam, dass alle Dateien, in die Sie das Datenarchiv für die Karte (.pkpass) aufnehmen möchten, hier aufgelistet sein sollten.
Als Ergebnis erhalten wir eine .pkpass-Datei, die auf dem Computer geöffnet werden kann. Wir sehen eine Vorschau der Karte, deren Erscheinungsbild vom Erscheinungsbild des Telefons abweichen kann.
All dies kann etwas einfacher gemacht werden. Apple bietet das signpass
Dienstprogramm ( Apple Wallet-Beispielmessgeräte ) an, das alle SHA-Berechnungen (die Datei manifest.json
kann in Ruhe gelassen werden) und die Erstellung von Signaturen übernimmt. Um es zu verwenden, müssen Sie ein Projekt signpass
und die signpass
Datei in einem Ordner mit allen erforderlichen Ressourcen signpass
.

Im Allgemeinen sollte die Struktur ungefähr so aussehen:

Führen Sie als nächstes den Befehl aus:
./signpass -p wallet
Brieftasche ist der Name des Ordners, in dem sich alle Ressourcen befinden. Die Ausgabe ist wallet.pkpass. Der Inhalt kann durch Entpacken von wallet.pkpass angezeigt werden.
unzip wallet.pkpass
Es ist möglich, dass die Erstellung von pkpass an das Backend gesendet wird. In diesem Fall muss das Zertifikat für die Pass-Typ-ID in Form von .p12 und das Kennwort dafür an die WWDR-Entwickler übertragen werden.
Anwendungsintegration
Damit die Anwendung Wallet Karten hinzufügen kann, müssen Sie diese Funktion in der App-ID und diese Funktion in den Funktionen des Projekts aktivieren.


Dies ist für die vollständige korrekte Arbeit mit Wallet erforderlich. Andernfalls ist es nicht möglich, Karten aus der Brieftasche zu lesen, und es ist beispielsweise nicht möglich zu verstehen, ob unsere Karte hinzugefügt wurde oder nicht. Es ist auch wichtig zu beachten, dass die Team-ID in pass.json mit der Team-ID übereinstimmen muss, oder Sie müssen sie manuell zu Berechtigungen hinzufügen. Dies kann die Situation beheben, aber ich habe dies nicht überprüft.

Karte hinzufügen
Das Hinzufügen von Karten ist sehr einfach:
guard let passPath = Bundle.main.path(forResource: "wallet", ofType: "pkpass") else { return } let error: ErrorPointer = ErrorPointer(nilLiteral: ()) guard let passData = NSData(contentsOfFile: passPath) else { return } let pass = PKPass(data: passData as Data, error: error) let passLibrary = PKPassLibrary() passLibrary.addPasses([pass]) { (status) in print(passLibrary.containsPass(pass)) }
Wiederum muss die .pkpass-Datei jedoch häufiger von Ihrem Server heruntergeladen werden.
Es ist erwähnenswert, dass PassKit ziemlich lesbare Fehler erzeugt, sodass Sie leicht verstehen können, was genau falsch gemacht wurde.
Um Informationen zu den in Wallet verfügbaren Karten zu erhalten, die sich auf Ihre Anwendung beziehen, müssen Sie sich an das PKPassLibrary-Objekt wenden.
let passLibrary = PKPassLibrary() let passes = passLibrary.passes()
So können Sie verstehen, ob die Karte hinzugefügt wurde oder nicht, und die Benutzeroberfläche aktualisieren. Darüber hinaus können über PKPassLibrary Karten aktualisiert und gelöscht werden. Karten können auch über Webdienste aktualisiert werden. In diesem Artikel wird eine solche Option jedoch nicht berücksichtigt.
Eindeutigkeitsprüfung
Da in Ihrem Dienst die Karte in der Regel an ein Konto gebunden ist, müssen Sie in der Anwendung höchstwahrscheinlich feststellen, ob die Karte dem aktuellen Benutzer gehört. Ich schlage vor, dies über serialNumber
. serialNumber
Sie beispielsweise die serialNumber
des Benutzers oder die Kartennummer fest.
Testen
Apple bietet pkpass-Beispiele für verschiedene Typen, auf die Sie sich konzentrieren können.
Apple Wallet Beispiele
Um zu sehen, wie die Karte aussieht, können Sie dem Projekt pkpass hinzufügen (siehe „Hinzufügen einer Karte“). Der Prozess des Hinzufügens / Entfernens wurde bereits oben erläutert. Es muss nur daran erinnert werden, dass die Anwendung die bereits hinzugefügten Karten nicht sieht, wenn die Karte für Wallet auf dem Konto eines Entwicklers erstellt wurde und die Entwicklung selbst von einem anderen Konto aus durchgeführt wurde (relevant für Outsourcing-Unternehmen). In diesem Fall können Sie problemlos Karten hinzufügen.
Mit einem QR-Code-Scanner können Sie überprüfen, ob die Informationen im Barcode korrekt codiert sind. Und es ist definitiv notwendig, die Richtigkeit der Arbeit mit diesem Scanner zu überprüfen.
Fazit
Der Artikel untersuchte den Prozess des Erstellens und Entwerfens einer Karte sowie den Prozess der Integration in die Anwendung und mögliche Probleme. Ich habe absichtlich keine Probleme mit der Integration in Webdienste und Kartenaktualisierungen angesprochen, und ich hoffe, dies im nächsten Artikel zu tun.
Verwendete Materialien:
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html
https://developer.apple.com/library/archive/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/TopLevel.html#//apple_ref/doc/uid/TP40012026-CH2-SW3
https://itechroof.wordpress.com/2015/11/30/apple-wallet-part-13/
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Updating.html
Besonderer Dank geht an mehdzor für das Entwicklerkonto für die Tests.