Accès aux données Salesforce à l'aide des API REST
Objectifs de formation
Une fois cette unité terminée, vous pourrez :
- générer une requête REST à l’aide de l’interface RestClient ;
- recevoir la réponse REST de Salesforce ;
- utiliser le kit de développement mobile pour traiter la réponse REST.
Envoi de requêtes REST
La classe RootViewController montre un aperçu des classes API REST dans le kit Mobile SDK. Examinons de plus près l’utilisation des classes API REST.
Utilisation des objets RestClient et RestRequest
Pour accéder aux données Salesforce via les API REST du kit de développement mobile, vous envoyez des requêtes à Salesforce et recevez les réponses dans votre application. Comment RootViewController envoie-t-il des requêtes sur le réseau ?
RestClient est votre point d’entrée vers tous les services REST. Les applications de Kit de développement mobile utilisent les méthodes RestClient pour fabriquer et envoyer des demandes REST. Vous accédez toujours à cette classe uniquement via son instance partagée :
RestClient.shared()
- Créez et initialisez une instance RestRequest. RestClient fournit pour cela un choix élargi de méthodes d’usine. Notre exemple crée une requête SOQL, mais vous pouvez sélectionner la méthode RestClient qui vous convient.
- Envoyez l’objet de la requête à Salesforce. RestClient authentifie automatiquement la requête avec les identifiants de l’utilisateur actif.
- Dans Xcode, ouvrez le fichier RootViewController.swift.
- Recherchez la méthode loadView(). L’implémentation lit un code semblable à :
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)") } } }
- l’instance partagée RestClient, qui génère un objet de requête à envoyer à Salesforce par le réseau ;
- l’objet RestRequest généré, qui contient une requête prédéfinie à l’API REST basée sur la chaîne SOQL fournie.
send(request: Request, _ completionBlock: @escaping (Result<RestResponse, RestClientError>) -> Void)
Dans ce cas, la closure finale détermine l’état de la réponse en lisant les membres success et failure de l’argument result. En cas de réussite, la closure reçoit les données de réponse et les transmet à une fonction de gestion distincte. En cas d’échec, la closure reçoit le message d'erreur, l’enregistre et revient.
{[weak self] (response, urlResponse) in ...
Traitement des réponses REST
La réception et la consommation de données Salesforce nécessite la capacité d’intercepter des rappels réseaux asynchrones. Le kit de développement mobile définit deux options pour cette tâche :
- méthode RestClient
- Lorsque vous appelez la fonction send, vous fournissez une closure finale. Salesforce envoie la réponse du serveur, encapsulée en tant qu’objet iOS, à votre closure.
- Le protocole RestClientDelegate
- Vous définissez quatre fonctions de rappel qui reçoivent des réponses de réussite et d’échec. Lorsque votre application envoie une requête REST, elle désigne la classe qui implémente ce protocole en tant que cible de la réponse du serveur.
En Objective-C, il est plus élégant d’utiliser le protocole SFRestDelegate, l’équivalent de RestClientDelegate, au lieu de rappels de blocs en ligne. Toutefois, dans les applications Swift, l’avantage d'une syntaxe closure finale offre une solution encore meilleure. Cette structure permet d’obtenir un enchaînement lisible et naturel, de la formation de la requête à la consommation de la réponse. Les closures en ligne sont également plus faciles à coder que le protocole RestClientDelegate.
Utilisation de la méthode RestClient send(request:_:) Méthode
Observons de plus près comment le modèle d’application Swift code la méthode send(request:_:).
- La classe de modèle RootViewController utilise la méthode d’usinekit de développement mobile RestClient pour créer une requête SOQL.
let request = RestClient.shared.request(forQuery: "SELECT Name FROM User LIMIT 10")
- La ligne suivante appelle la méthode send pour envoyer la requête à Salesforce. Cette méthode attend un argument de closure pour recevoir la réponse du serveur et gérer la réussite ou l’échec. Par exemple :Vous avez maintenant une closure finale facile à repérer, ajoutée juste après la parenthèse fermante de la méthode.
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)") } }
- Lorsque la réponse arrive, la liste de capture de la closure reçoit un objet de réponse (result).Vous remarquerez l’utilisation explicite de [weak self] pour remplacer la référence implicite à self. Comme les réponses REST sont asynchrones, vous ne pouvez pas faire confiance à la classe qui a défini la closure de réussite pour rester en mémoire lorsque la réponse arrive. Pour éviter des cycles de rétention inutiles, utilisez [weak self] puis validez self dans la closure avant de l’utiliser.
{ [weak self] (result) in }
- Si la réponse indique la réussite, votre application peut continuer son flux prévu, pour afficher une liste des noms de contact dans sa vue du tableau. L’application modèle transmet la réponse à une autre méthode locale, handleSuccess(response:request:):
case .success(let response): self?.handleSuccess(response: response, request: request)
- Pour les échecs, le Kit de développement mobile envoie à votre requête .failure un objet de réponse (error) de type Error. Cette application enregistre un message d’erreur, puis revient.
case .failure(let error): SalesforceLogger.d(RootViewController.self, message:"Error invoking: \(request) , \(error)") // Nothing more to do, so just return
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() } }
Utilisation du protocole RestClientDelegate
En plus de clarifier le code, le protocole RestClientDelegate analyse la catégorie d’un échec et envoie la réponse d’échec à un gestionnaire spécifique à la catégorie. Si votre classe adopte le protocole RestClientDelegate, elle peut mettre en œuvre quatre fonctions de gestionnaire de réponses.
- request(_:didLoadResponse:) : la requête a été traitée. Le délégué reçoit la réponse au format JSON. Ce rappel indique la réussite. Il contient le même code que vous aviez intégré à la closure de réussite de la méthode send(request:onFailure: onSuccess:).
- request(_:didFailLoadWithError:) : la requête n’a pas pu être traitée. Le délégué reçoit un message d'erreur. Dans la méthode send(request:onFailure:onSuccess:) n’étant pas associée au délégué, cette erreur serait gérée dans la closure onFailure.
- requestDidCancelLoad(_:) : la requête a été annulée par un facteur externe, par exemple l’intervention de l’administrateur, une panne de réseau ou un autre événement inattendu. Le délégué ne reçoit aucune valeur de retour. Dans la méthode send(request:onFailure:onSuccess:) n’étant pas associée au délégué, cet échec serait géré dans la closure onFailure.
- requestDidTimeout(_:) : le serveur Salesforce n’a pas répondu à temps. Le délégué ne reçoit aucune valeur de retour. Dans la méthode send(request:onFailure:onSuccess:) n’étant pas associée au délégué, cet échec serait géré dans la closure onFailure.
Le kit de développement mobile fournit des réponses de réussite au rappel request(_:didLoadResponse:). Si vous vous demandez comment décoder la réponse du réseau, ne vous inquiétez pas. Par défaut Mobile SDK met en forme la réponse en tant que JSON convivial dans un objet de dictionnaire. Ce dictionnaire contient une clé « records » dont la valeur est un tableau d’enregistrements Salesforce. Les conditions d’erreur, d’annulation et d’expiration sont chacune traitées par leurs propres gestionnaires, ce qui facilite la mise en œuvre d’actions spécifiques en fonction des types d’échecs.
Et voilà, la boucle est bouclée. Nous avons initialisé l’application, connecté un utilisateur, émis une requête REST et affiché la réponse REST. L’application est maintenant au repos, car elle ne sait rien faire d’autre. Développons un peu votre application en ajoutant la prise en charge de quelques interactions des utilisateurs, par exemple le balayage vers la gauche pour supprimer.