Maîtriser les requêtes HTTP avec Alamofire en Swift : GET, POST et gestion des réponses JSON

Alamofire est une bibliothèque réseau populaire pour Swift, conçue pour simplifier les opérations HTTP. Elle encapsule les complexités réseau, offrant une API intuitive pour envoyer des requêtes comme GET, POST, PUT et DELETE. Cette libaririe supporte la sérialisation des réponses, l'upload et le download de fichiers, ainsi que la configuration flexible des en-têtes, le tout avec un code Swift propre et maintenable.

Requêtes GET avec Alamofire

Pour effectuer une requête GET, utilisez AF.request qui est par défaut en méthode GET. Voici un exemple de code :

func retrieveData() {
    print("Lancement d'une requête GET")
    let endpointURL = "https://exemple.com/api/donnees"
    AF.request(endpointURL).responseData { response in
        switch response.result {
        case .success(let payload):
            if let jsonObj = try? JSONSerialization.jsonObject(with: payload) {
                print("Succès : \(jsonObj)")
            }
        case .failure(let err):
            print("Échec : \(err)")
        }
    }
}

Requêtes POST avec paramètres

Pour une requête POST, spécifiez la méthode .post et passez les paramètres. Utilisez .responseJSON pour obtenir directement une réponse JSON :

func sendPostData() {
    print("Envoi d'une requête POST")
    let targetURL = "https://api.service.com/utilisateur"
    let bodyParameters = ["nom": "alice", "secret": "abc123"]
    AF.request(targetURL, method: .post, parameters: bodyParameters, encoding: JSONEncoding.default).responseJSON { resp in
        switch resp.result {
        case .success(let result):
            print("Réponse POST : \(result)")
        case .failure(let error):
            print("Erreur : \(error)")
        }
    }
}

Les requêtes PUT et DELETE suivent le même schéma, en changeant la méthode. Les paramètres peuvent être de type Encodable, comme illustré ci-dessous :

struct UserProfile: Encodable {
    let username: String
    let token: String
}

let user = UserProfile(username: "bob", token: "xyz789")
AF.request("https://httpbin.org/post",
           method: .post,
           parameters: user,
           encoder: JSONParameterEncoder.default)
    .response { resp in
        print(resp)
    }

Configuration des en-têtes HTTP

Alamofire propose trois façons de définir les en-têtes :

1. Construction sans arguments initiaux :

var headerSet = HTTPHeaders()
headerSet.add(name: "Authorization", value: "Bearer token123")
headerSet.add(.contentType("application/json"))

2. Via un tableau de HTTPHeader :

let customHeaders: HTTPHeaders = [
    HTTPHeader(name: "Authorization", value: "Bearer token123"),
    .accept("application/json")
]
AF.request("https://httpbin.org/headers", headers: customHeaders).responseJSON { resp in
    print(resp)
}

3. Via un dictionnaire clé-valeur :

let simpleHeaders: HTTPHeaders = [
    "Authorization": "Bearer token123",
    "Accept": "application/json"
]
AF.request("https://httpbin.org/headers", headers: simpleHeaders).responseJSON { resp in
    print(resp)
}

Traitement des réponses

Alamofire fournit plusieurs sérialiseurs pour les réponses :

1. DataResponseSerializer pour obtenir des données brutes :

AF.request("https://httpbin.org/get").responseData { response in
    print("Données : \(response)")
}

2. StringResponseSerializer pour une réponse en chaîne de caractères :

AF.request("https://httpbin.org/get").responseString { response in
    print("Chaîne : \(response)")
}

3. JSONResponseSerializer pour une réponse JSON :

AF.request("https://httpbin.org/get").responseJSON { response in
    print("JSON : \(response)")
}

Téléchargement de fichiers

Pour télécharger des données :

AF.download("https://httpbin.org/image/png").responseData { response in
    if let image = response.value.map(UIImage.init) {
        // Traiter l'image
    }
}

Pour télécharger vers un dossier spécifique :

let dest = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
AF.download("https://httpbin.org/image/png", to: dest).response { resp in
    if resp.error == nil, let filePath = resp.fileURL?.path {
        let img = UIImage(contentsOfFile: filePath)
    }
}

Suivre la progression du téléchargement :

AF.download("https://httpbin.org/image/png")
    .downloadProgress { prog in
        print("Progression : \(prog.fractionCompleted)")
    }
    .responseData { response in
        // Gérer les données
    }

Reprendre un téléchargement annulé :

var resumeData: Data?
let task = AF.download("https://httpbin.org/image/png").responseData { _ in }

task.cancel { data in
    resumeData = data
}

AF.download(resumingWith: resumeData ?? Data()).responseData { response in
    // Continuer le traitement
}

Upload de fichiers

Uploader des données brutes :

let fileData = Data("contenu".utf8)
AF.upload(fileData, to: "https://httpbin.org/post").response { resp in
    print(resp)
}

Uploader un fichier depuis l'application :

if let url = Bundle.main.url(forResource: "media", withExtension: "mp4") {
    AF.upload(url, to: "https://httpbin.org/post").response { resp in
        print(resp)
    }
}

Uploader des données multipart :

AF.upload(multipartFormData: { formData in
    formData.append(Data("premiere_partie".utf8), withName: "segment1")
    formData.append(Data("deuxieme_partie".utf8), withName: "segment2")
}, to: "https://httpbin.org/post")
    .response { resp in
        print(resp)
    }

Surveiller la progression de l'upload :

if let videoURL = Bundle.main.url(forResource: "video", withExtension: "mov") {
    AF.upload(videoURL, to: "https://httpbin.org/post")
        .uploadProgress { prog in
            print("Progression upload : \(prog.fractionCompleted)")
        }
        .response { resp in
            print(resp)
        }
}

Étiquettes: Alamofire Swift iOS HTTP JSON

Publié le 29 mai à 14h34