Commencer avec Alamofire

Pour commencer à intégrer Alamofire dans votre projet iOS, vous pouvez ajouter la bibliothèque en utilisant Swift Package Manager, CocoaPods ou Carthage. Swift Package Manager est l'approche recommandée car il est intégré dans Xcode. Ajoutez le paquet Alamofire en naviguant dans FileAjouter des paquets[ et en entrant l'URL du dépôt . Spécifiez la version 5.0.0 ou ultérieure. Sinon, si vous utilisez CocoaPods, ajoutez à votre fichier Pod et lancez . Une fois la dépendance intégrée, importez Alamofire dans tout fichier Swift où vous avez besoin de fonctionnalités réseau :

import Alamofire

Alamofire , l'alias fournit un point d'entrée pratique pour toutes les opérations HTTP courantes. Sous le capot, il utilise Apples mais supprime la plaque de chaudière comme la gestion de file d'attente, l'encodage des paramètres et la validation des réponses. Cela vous permet de vous concentrer sur la logique d'entreprise plutôt que la plomberie de réseau.

Exécution des demandes GET

La saisie des données d'un paramètre RESTful est l'opération la plus courante. Alamofire rend les requêtes GET concises et lisibles. L'exemple suivant récupère une liste d'utilisateurs d'une API hypothétique :

AF.request("https://api.example.com/users")
 .validate()
 .responseDecodable(of: [User].self) { response in
 switch response.result {
 case .success(let users):
 print("Fetched \(users.count) users")
 case .failure(let error):
 print("Request failed with error: \(error)")
 }
 }

Remarquez l'utilisation de , qui fait appel au protocole Swift=s pour analyser automatiquement JSON dans des objets modèles. Définir une structure qui est conforme à (ou ). Cette approche élimine la sérialisation manuelle JSON et améliore la sécurité de type.

Ajouter des paramètres de requête et des en-têtes

De nombreuses API REST nécessitent des paramètres de requête ou des en-têtes HTTP personnalisés. Alamofire accepte les paramètres comme dictionnaire et gère l'encodage automatiquement pour les requêtes GET (les paramètres sont ajoutés à l'URL).

let parameters: Parameters = ["page": 1, "limit": 20]
let headers: HTTPHeaders = [
 "Authorization": "Bearer YOUR_TOKEN",
 "Accept": "application/json"
]

AF.request("https://api.example.com/users",
 parameters: parameters,
 headers: headers)
 .validate()
 .responseDecodable(of: [User].self) { response in
 // handle response
 }

Alamofire encode automatiquement les paramètres et les attache à l'URL de la requête. Pour l'encodage personnalisé, vous pouvez spécifier une instance explicite , telle que .

Validation de la réponse

La méthode vérifie automatiquement les codes d'état HTTP dans la plage 200-299 et rejette les réponses avec un type de contenu non acceptable. Vous pouvez également ajouter des critères de validation personnalisés. Par exemple, pour accepter seulement 200 et 201 codes d'état :

.validate(statusCode: [200, 201])

Les erreurs de validation sont signalées comme des erreurs dans le gestionnaire de réponse, vous permettant d'implémenter une gestion cohérente des erreurs tout au long de votre application.

Envoi des données POST

La création ou la mise à jour des ressources nécessite généralement une requête POST avec un corps de requête. Alamofire prend en charge plusieurs stratégies d'encodage, avec étant le plus courant pour les API REST. L'exemple suivant envoie un nouvel objet utilisateur au serveur :

let newUser: [String: Any] = [
 "name": "Jane Doe",
 "email": "[email protected]"
]

AF.request("https://api.example.com/users",
 method: .post,
 parameters: newUser,
 encoding: JSONEncoding.default)
 .validate()
 .responseDecodable(of: User.self) { response in
 switch response.result {
 case .success(let createdUser):
 print("User created: \(createdUser)")
 case .failure(let error):
 print("Error creating user: \(error)")
 }
 }

Si l'API attend des données de formulaire encodées par URL (p. ex. pour l'échange de jetons OAuth), utilisez plutôt . Pour les téléchargements de fichiers ou les données mixtes, Alamofire fournit qui construit une requête multiparties. Exemple :

AF.upload(multipartFormData: { multipartFormData in
 multipartFormData.append(Data("Jane Doe".utf8), withName: "name")
 multipartFormData.append(imageData, withName: "avatar", fileName: "avatar.jpg", mimeType: "image/jpeg")
}, to: "https://api.example.com/users")
 .validate()
 .responseDecodable(of: User.self) { response in
 // handle response
 }

Travailler avec d'autres méthodes HTTP

Les API REST nécessitent souvent des opérations PUT (mise à jour complète), PATCH (mise à jour partielle) et DELETE (suppression). Alamofire les gère avec la même méthode ; il suffit de modifier le paramètre .

PUT et PATCH

Pour mettre à jour une ressource existante, utilisez ou . L'organisme de demande contient les champs mis à jour:

let updatedFields: [String: Any] = ["name": "Jane Smith"]
AF.request("https://api.example.com/users/123",
 method: .patch,
 parameters: updatedFields,
 encoding: JSONEncoding.default)
 .validate()
 .responseDecodable(of: User.self) { response in
 // handle updated user
 }

DÉLÈVE

Supprimer une ressource n'exige généralement aucun organisme de requête. La réponse peut être vide ou renvoyer un message de confirmation :

AF.request("https://api.example.com/users/123",
 method: .delete)
 .validate()
 .response { response in
 if let error = response.error {
 print("Delete failed: \(error)")
 } else {
 print("User deleted successfully")
 }
 }

Vérifiez toujours la documentation de l'API pour connaître les codes d'état attendus (p. ex. 204 Aucun contenu).

Gestion avancée des erreurs et surveillance du réseau

La gestion d'erreurs robuste est essentielle pour une expérience utilisateur sans faille. Alamofire signale des erreurs par le type , qui distingue entre les erreurs réseau (délai, aucune connexion), les erreurs serveur (code de mauvais état) et les erreurs de sérialisation (JSON non valide). Vous pouvez inspecter l'erreur pour fournir des commentaires spécifiques:

switch response.result {
case .success(let value):
 // handle success
case .failure(let error):
 if let afError = error.asAFError {
 switch afError {
 case .sessionTaskFailed(let sessionError):
 print("Network issue: \(sessionError.localizedDescription)")
 case .responseValidationFailed(let reason):
 print("Validation failed: \(reason)")
 default:
 print("Other Alamofire error: \(afError.localizedDescription)")
 }
 }
}

Reachability réseau

Avant de faire des demandes, vous pouvez vérifier la disponibilité du réseau. Alamofire , surveille les changements de connectivité.

let reachabilityManager = NetworkReachabilityManager()
reachabilityManager?.startListening { status in
 switch status {
 case .notReachable:
 print("Network is not reachable")
 case .reachable(.cellular):
 print("Connected via cellular")
 case .reachable(.ethernetOrWiFi):
 print("Connected via WiFi")
 case .unknown:
 print("Unknown status")
 }
}

Pour des motifs plus avancés, envisager de combiner la facilité d'accès avec un mécanisme de réessayer, comme le réessayer des demandes échouées lorsque la connectivité est rétablie.

Meilleures pratiques pour la production-réapprovisionnement en réseau

En suivant les modèles établis, votre couche de réseautage sera maintenue, sécurisée et performante.

1. Adopter des modèles codables

Toujours définir les types Swift qui sont conformes à (ou ) pour l'analyse de la réponse. Cela élimine la manipulation manuelle JSON et réduit les bogues. Utilisez ou le niveau inférieur si vous avez besoin de contenu dynamique. Apples Codable guide couvre la cartographie avancée avec des clés personnalisées.

2. Authentification plus sûre et gestion des jetons

Ne jamais coder dur API touches ou jetons. Stockez des valeurs sensibles dans la chaîne-clés et attachez-les aux requêtes via l'en-tête . Pour les flux d'OAuth, implémentez un intercepteur de rafraîchissement de jetons. Alamofire , le protocole vous permet de réessayer automatiquement les requêtes après avoir obtenu un nouveau jeton.

class AuthInterceptor: RequestInterceptor {
 func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
 var request = urlRequest
 request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
 completion(.success(request))
 }

 func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
 // Check if error is 401, refresh token, then retry
 completion(.retryWithDelay(1.0))
 }
}

3. Concurrence avec async/attendu

Alamofire 5 prend en charge le modèle de concurrence Swift. Utilisez les versions des méthodes de requête pour écrire le nettoyeur, code linéaire:

do {
 let users = try await AF.request("https://api.example.com/users")
 .serializingDecodable([User].self)
 .value
 print("Users: \(users)")
} catch {
 print("Error: \(error)")
}

Combinez ceci avec la concurrence structurée (groupes de tâches, acteurs) pour gérer plusieurs requêtes et éviter l'enfer de callback.

4. Mettre en œuvre le cache

Pour réduire les appels réseau et améliorer le support hors ligne, configurer les politiques de cache. Alamofire respecte le (par exemple, ). Vous pouvez également utiliser un personnalisé avec une capacité de disque appropriée:

let cache = URLCache(memoryCapacity: 10 * 1024 * 1024,
 diskCapacity: 50 * 1024 * 1024,
 diskPath: "networking_cache")
let session = Session(configuration: URLSessionConfiguration.default)
session.sessionConfiguration.urlCache = cache

5. Testez votre calque de réseautage

Écrire des tests unitaires pour vos clients API en utilisant des données simulées. Alamofire , peut être injecté avec un protocole simulé qui renvoie des réponses prédéfinies. Envisagez d'utiliser des bibliothèques comme ou l'abstraction intégrée .

6. Utiliser un gestionnaire de réseau centralisé

Créez une seule classe qui configure une instance avec URL de base, en-têtes, intercepteurs et cache partagé. Cela empêche la duplication et facilite l'échange de politiques ou la simulation de la couche entière. Exemple :

class APIClient {
 static let shared = APIClient()
 private let session: Session

 private init() {
 let config = URLSessionConfiguration.default
 config.timeoutIntervalForRequest = 30
 config.urlCache = URLCache.shared
 session = Session(configuration: config, interceptor: AuthInterceptor())
 }

 func fetchUsers() async throws -> [User] {
 return try await session.request("\(baseURL)/users")
 .serializingDecodable([User].self)
 .value
 }
}

Pour une compréhension complète des modèles de réseautage, reportez-vous au documentation d'utilisation avancée d'Alamofire. De plus, le tutoriel REST API à reestfulapi.net offre des informations précieuses sur la conception d'API robuste.

En suivant ces lignes directrices et en tirant parti de l'API expressive d'Alamofire, vous pouvez construire une couche de réseau qui est à la fois puissante et facile à entretenir. La bibliothèque abstraction de nombreux aspects fastidieux du chargement d'URL tout en vous donnant le contrôle complet lorsque vous en avez besoin.