Erfassen Sie Ihre Fortschritte
Trailhead-Startseite
Trailhead-Startseite

Zugriff auf Salesforce-Daten über REST-APIs

Lernziele

Nachdem Sie diese Lektion abgeschlossen haben, sind Sie in der Lage, die folgenden Aufgaben auszuführen:

  • Absetzen einer REST-Anforderung mit der RestClient-Schnittstelle
  • Empfangen der REST-Antwort von Salesforce
  • Verwenden des Mobile SDK zum Verarbeiten der REST-Antwort

Senden von REST-Anforderungen

Die RootViewController-Klasse hat Ihnen einen kleinen Einblick in die Funktionsweise der REST API-Klassen in Mobile SDK gegeben. Werfen wir einen genaueren Blick darauf, wie Sie REST-API-Klassen verwenden.

Verwenden von RestClient- und RestRequest-Objekten

Um über REST-APIs des Mobile SDK auf Salesforce-Daten zuzugreifen, senden Sie Anforderungen an Salesforce und empfangen die Antworten in Ihrer Anwendung. Wie sendet RootViewController Netzwerkanforderungen?

RestClient ist Ihr Einstiegspunkt zu allen REST-Services. Mobile SDK-Anwendungen verwenden RestClient-Methoden zum Erstellen und Senden von REST-Anforderungen. Sie greifen stets nur über ihre gemeinsame Instanz auf diese Klasse zu:

RestClient.shared()

Hier wird die standardmäßige Sequenz "Anforderung senden" in der loadView()-Methode demonstriert.
  1. Erstellen und initialisieren Sie eine RestRequest-Instanz. RestClient bietet zu diesem Zweck ein umfassendes Sortiment an Factory-Methoden. In unserem Beispiel wird eine SOQL-Abfrageanforderung erstellt, Sie können jedoch jede beliebige RestClient-Methode wählen, die Ihre Zwecke erfüllt.
  2. Senden Sie das Anforderungsobjekt an Salesforce. RestClient authentifiziert die Anforderung automatisch mit den Anmeldedaten des aktuellen Benutzers.
Lassen Sie uns den Code näher betrachten.
  1. Öffnen Sie in Xcode die Datei RootViewController.swift.
  2. Suchen Sie die loadView()-Methode. Die Implementierung liest in etwa Folgendes:
    override func loadView() {
        super.loadView()
        self.title = "Mobile SDK Sample App"
        let request = RestClient.shared.request(forQuery: "SELECT Name FROM Contact LIMIT 10")        
        RestClient.shared.send(request: request) { [weak self] (result) in
            switch result {
                case .success(let response):
                    self?.handleSuccess(response: response, request: request)
                case .failure(let error):
                     SalesforceLogger.d(RootViewController.self, 
                         message:"Error invoking: \(request) , \(error)")
            }
        }
    }
Nach dem Aufrufen der Superklassenmethode und Einstellen des Ansichtstitels erstellt und sendet diese Methode eine REST-Anforderung. Dazu nutzt sie Folgendes
  • Die freigegebene RestClient-Instanz generiert ein Anforderungsobjekt, das über das Netzwerk an Salesforce gesendet werden soll.
  • Das generierte RestClient-Objekt enthält eine vorformatierte REST-API-Anforderung, die auf der angegebenen SOQL-Zeichenfolge basiert.
Um REST-Antworten zu verarbeiten, verwendet RootViewController die folgende Methode:
send(request: Request, _ completionBlock: @escaping (Result<RestResponse, RestClientError>) -> Void)
Mit dieser Methode stellen Sie einen nachgeschalteten Abschluss zur Verfügung, um entweder Erfolg oder Misserfolg zu verarbeiten. Wenn Sie mit der entsprechenden Syntax nicht vertraut sind, erfahren Sie hier, wie sie funktioniert. Ein Abschluss ist syntaktisch ein Funktionsblock, der Argumente verwenden und einen Wert zurückgeben kann. Wenn der Typ des letzten Arguments einer Funktion ein Abschluss ist, können Sie dieses Element aus der Parameterliste entfernen. Stattdessen fügen Sie den Funktionsabschluss direkt nach der schließenden Klammer des Aufrufs hinzu. Ein nachgeschalteter Abschluss vereinfacht Ihre Syntax und steht allein als erwartetes Ergebnis des Funktionsaufrufs, der darauf folgt.

In diesem Fall bestimmt der nachgeschaltete Abschluss den Antwortstatus, indem die Member success und failure des Arguments result gelesen werden. Im Erfolgsfall empfängt der Abschluss die Antwortdaten und übergibt sie an eine separate Verarbeitungsfunktion. Im Fehlerfall empfängt der Abschluss die Fehlermeldung, protokolliert sie und kehrt zurück.

Auf diese Weise senden Sie Anforderungen und leiten Antworten mithilfe eines Fertigstellungsabschlusses weiter. Vielleicht haben Sie Fragen hierzu. Zum Beispiel: "Was bedeutet diese Zeile?"
{[weak self] (response, urlResponse) in ...
Und: "Gibt es andere Optionen?" Lesen Sie weiter.

Verarbeiten von REST-Antworten

Der Empfang und die Verwertung der Daten von Salesforce setzt die Fähigkeit voraus, asynchrone Netzwerkrückmeldungen abzufangen. Das Mobile SDK definiert zwei Optionen für diese Aufgabe:

RestClient-Methode
Sie stellen beim Aufrufen der send-Funktion einen nachgeschalteten Abschluss bereit. Salesforce sendet die Serverantwort als umschlossenes iOS-Objekt an Ihren Abschluss.
RestClientDelegate-Protokoll
Sie definieren vier Rückmeldungsfunktionen, die Erfolgs- und Fehlerantworten empfangen. Wenn Ihre Anwendung eine REST-Anforderung sendet, gibt sie die Klasse, die dieses Protokoll implementiert, als Ziel für die Antwort des Servers an.

In Objective-C ist es eleganter, das SFRestDelegate-Protokoll, also die Entsprechung zu RestClientDelegate in Objective-C, anstelle von Inline-Blockrückmeldungen zu verwenden. In Swift-Anwendungen haben Sie den Vorteil der Syntax mit nachgeschaltetem Funktionsabschluss, die eine noch bessere Lösung bietet. Diese Vorgehensweise ergibt einen natürlichen, lesbaren Ablauf von der Bildung der Anforderung bis zur Auswertung der Antwort. Inline-Funktionsabschlüsse sind zudem einfacher zu kodieren als das RestClientDelegate-Protokoll.

Verwenden der RestClient-Methode send(request:_:)

Sehen wir uns genauer an, wie die Swift-Vorlagenanwendung die send(request:_:)-Methode codiert.

  1. Die Vorlagenklasse RootViewController verwendet die Factory-Methode RestClient im Mobile SDK zum Erstellen einer SOQL-Anforderung.
    let request = RestClient.shared.request(forQuery: "SELECT Name FROM User LIMIT 10")
  2. In der nächsten Zeile ruft sie die send-Methode auf, um die Anforderung an Salesforce zu weiterzuleiten. Diese Methode erwartet, dass ein Abschlussargument die Antwort des Servers empfängt und Erfolg oder Misserfolg verarbeitet. Beispiel:
    let request = RestClient.shared.request(forQuery: "SELECT Name FROM User LIMIT 10")
    RestClient.shared.send(request: request) 
    { [weak self] (result) in
        switch result {
            case .success(let response):
                self?.handleSuccess(response: response, request: request)
            case .failure(let error):
                SalesforceLogger.d(RootViewController.self, 
                    message:"Error invoking: \(request) , \(error)")
        }
    }
    Jetzt haben Sie einen einfach zu erkennenden Abschluss, der direkt nach der schließenden Klammer der Methode hinzugefügt wird.
  3. Wenn die Antwort eingeht, erhält die Erfassungsliste des Abschlusses ein Antwortobjekt (result).
    { [weak self] (result) in
        
    }
    Beachten Sie die explizite Verwendung von [weak self] zum Ersetzen des impliziten Verweises auf self. Da REST-Antworten asynchron sind, können Sie nicht darauf vertrauen, dass die Klasse, die den Abschluss "Erfolg" definiert hat, noch im Arbeitsspeicher ist, wenn die Antwort eingeht. Um unnötige Haltezyklen zu vermeiden, verwenden Sie [weak self] und validieren Sie dann self im Abschluss, bevor Sie ihn verwenden.
  4. Wenn die Antwort als Erfolg gewertet wird, kann Ihre Anwendung ihren beabsichtigten Flow fortsetzen, um eine Liste der Kontaktnamen in ihrer Tabellenansicht anzuzeigen. Die Vorlagenanwendung übergibt die Antwort an eine andere lokale Methode, handleSuccess(response:request:):.
    case .success(let response):
        self?.handleSuccess(response: response, request: request)
  5. Bei Misserfolgen sendet das Mobile SDK an Ihren .failure-Fall ein Antwortobjekt (error) des Typs Error. Diese Anwendung protokolliert eine Fehlermeldung und fährt mit der Rückgabe fort.
    case .failure(let error):
        SalesforceLogger.d(RootViewController.self, 
            message:"Error invoking: \(request) , \(error)")
            // Nothing more to do, so just return
Hier ist die Funktion handleSuccess(response:request:).
func handleSuccess(response: RestResponse, request: RestRequest) {
    guard let jsonResponse  = try? response.asJson() as? [String:Any], 
        let records = jsonResponse["records"] as? [[String:Any]]  else {
            SalesforceLogger.d(RootViewController.self, 
                message:"Empty Response for : \(request)")
            return
    }
    SalesforceLogger.d(type(of:self), message:"Invoked: \(request)")
    DispatchQueue.main.async {
        self.dataRows = records
        self.tableView.reloadData()
    }
}
Diese Funktion verwendet sowohl das Antwortobjekt als auch das ursprüngliche Anforderungsobjekt. Wenn alles wie erwartet verläuft, sendet das Mobile SDK an den .success-Fall ein Antwortobjekt (result) des Typs Dictionary<String, Any>. Selbst wenn eine Anforderung erfolgreich war, kann der Server jedoch ein gültiges, aber unbrauchbares Ergebnis zurückgeben, z. B. wenn Sie eine Löschanforderung gesendet haben. Die Funktion handleSuccess(response:request:) bereitet sich auf den schlimmsten Fall vor, indem sie die Antwort mit einer "guard"-Anweisung in den erwarteten Typ konvertiert. Nach erfolgreicher Konvertierung speichert diese Funktion die angeforderten Datensätze in ihrer lokalen Variablen dataRows und weist die Tabellenansicht an, ihre Daten neu zu laden. Woher bezieht die Tabellenansicht ihre Daten? Ja genau, aus der Variablen dataRows.

Verwendung des RestClientDelegate-Protokolls

Das RestClientDelegate-Protokoll bietet nicht nur eine klare Codestruktur, sondern analysiert auch die Fehlerkategorie und sendet die Fehlerantwort an einen kategoriespezifischen Handler. Wenn Ihre Klasse das RestClientDelegate-Protokoll einsetzt, implementiert es vier Antworthandlerfunktionen.

  • request(_:didLoadResponse:): Anforderung wurde verarbeitet. Der Delegat erhält die Antwort im JSON-Format. Diese Rückmeldung bedeutet Erfolg. Sie enthält denselben Code, wie Sie ihn im Erfolgs-Funktionsabschluss der send(request:onFailure:onSuccess:)-Methode platziert haben.
  • request(_:didFailLoadWithError:): Anforderung konnte nicht verarbeitet werden. Der Delegat erhält eine Fehlermeldung. In der Nicht-Delegat-Methode send(request:onFailure:onSuccess:) würden Sie diesen Fehler im onFailure-Funktionsabschluss abfangen.
  • requestDidCancelLoad(_:): Anforderung wurde aufgrund einer externen Einwirkung abgebrochen, z. B. Administratoreingriff, Netzwerkstörung oder ein anderes unerwartetes Ereignis. Der Delegat erhält keinen Rückgabewert. In der Nicht-Delegat-Methode send(request:onFailure:onSuccess:) würden Sie diesen Fehler im onFailure-Funktionsabschluss abfangen.
  • requestDidTimeout(_:): Der Salesforce-Server hat nicht zeitgerecht geantwortet. Der Delegat erhält keinen Rückgabewert. In der Nicht-Delegat-Methode send(request:onFailure:onSuccess:) würden Sie diesen Fehler im onFailure-Funktionsabschluss abfangen.

Das Mobile SDK übergibt Erfolgsantworten an die request(_:didLoadResponse:)-Rückmeldung. Sie brauchen sich keine Sorgen darüber zu machen, wie die Antwort aus dem Netzwerk zu decodieren ist: Mobile SDK formatiert die Antwort standardmäßig und leicht lesbar als JSON in einem Datenverzeichnisobjekt. Das Datenverzeichnis enthält den Schlüssel "Datensätze", dessen Wert ein Array von Salesforce-Datensätzen ist. Fehler-, Abbruch- und Timeout-Bedingungen werden jeweils speziellen Handlern zugeordnet, sodass spezifische Aktionen auf der Basis von Fehlertypen einfacher implementiert werden können.

Und voilà – damit schließt sich der Kreis. Wir haben die Anwendung initialisiert, einen Benutzer angemeldet, eine REST-Anforderung ausgegeben und die REST-Antwort angezeigt. Die Anwendung ist nun im Ruhezustand (at), da es für sie vorerst nichts weiter zu tun gibt. Wir können Ihre Anwendung noch etwas pfiffiger machen, indem wir Ihr die Unterstützung von Benutzerinteraktionen hinzufügen, beispielsweise "Streichen nach links" zum Löschen.