Să începem cu Alamofire

Pentru a începe integrarea Alamofire în proiectul dvs. iOS, puteţi adăuga biblioteca folosind Swift Package Manager, CocoaPods sau Cartagina. Swift Package Manager este abordarea recomandată deoarece este construită în Xcode. Adăugaţi pachetul Alamofire prin navigare la File[] → Adăugaţi pachete[] şi introduceţi URL-ul depozitului . Specificaţi versiunea 5.0 sau mai târziu. Alternativ, dacă utilizaţi CocoaPods, adăugaţi la fişierul dvs. Podfile şi fugiţi . Odată ce dependenţa este integrată, importaţi Alamofire în orice fişier Swift unde aveţi nevoie de funcţionalitate reţea:

import Alamofire

Alamofire alias oferă un punct de intrare convenabil pentru toate operațiunile comune HTTP. Sub capotă, utilizează Apple

Efectuarea cererilor GET

Aducerea datelor dintr-un obiectiv RESTIF este cea mai comună operaţiune. Alamofire face GET cereri concise şi lizibile. Următorul exemplu preia o listă de utilizatori dintr-un API ipotetic:

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)")
 }
 }

Observați utilizarea protocolului , care pârghie Swift

Adăugare parametri de interogare și antete

Multe API-uri REST necesită parametri de interogare sau antete HTTP personalizate. Alamofire acceptă parametrii ca dicționar și se ocupă automat de codificarea cererilor GET (parametrele sunt anexate URL-ului). Antetele sunt adăugate prin parametrul :

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 codifică automat parametrii și îi atașează la URL-ul cererii. Pentru codificarea personalizată, puteți specifica un exemplu explicit , cum ar fi .

Validarea răspunsului

Metoda verifică automat codurile de stare HTTP din intervalul 200/299 și respinge răspunsurile cu un tip de conținut inacceptabil. De asemenea, puteți adăuga criterii de validare personalizate. De exemplu, să acceptați doar 200 și 201 coduri de stare:

.validate(statusCode: [200, 201])

Eșecurile de validare sunt raportate ca erori în handler-ul de răspuns, permițându-vă să implementați o manipulare coerentă a erorilor pe parcursul aplicației.

Trimiterea datelor postate

Crearea sau actualizarea resurselor necesită de obicei o cerere POST cu un organism de cerere. Alamofire suportă strategii multiple de codificare, cu fiind cel mai comun pentru API-urile REST. Următorul exemplu trimite un nou obiect de utilizator serverului:

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)")
 }
 }

Dacă API se așteaptă ca datele din formularul URL-codat (de exemplu, pentru schimbul de jetoane OAuth), să utilizeze în schimb. Pentru încărcarea fișierelor sau date mixte, Alamofire furnizează care construiește o cerere multipart. Exemplu:

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
 }

Lucrul cu alte metode HTTP

API-urile restrânse necesită adesea Put (actualizare completă), PATT (actualizare parțială) și DELETE (eliminare). Alamofire se ocupă de acestea cu aceeași metodă ; pur și simplu modifică parametrul .

PUT and PACTCH

Pentru actualizarea unei resurse existente, utilizați sau . Organismul de cerere conține câmpurile actualizate:

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
 }

DELETE

Eliminarea unei resurse nu necesită de obicei nici un organism de cerere. Răspunsul ar putea fi gol sau returna un mesaj de confirmare:

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")
 }
 }

Verificați întotdeauna documentația API pentru codurile de stare preconizate (de exemplu 204 No Content).

Manipularea și monitorizarea rețelei de erori avansate

Manipularea erorilor robuste este critică pentru o experiență de utilizator fără probleme. Alamofire raportează erori prin tipul , care diferențiază între erorile de rețea (Timeout, nici o conexiune), erorile serverului (cod de stare proastă) și eșecurile de serilizarea (invalid JSON). Puteți inspecta eroarea pentru a furniza feedback specific:

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)")
 }
 }
}

Reacsabilitatea rețelei

Înainte de a face cereri, este posibil să doriți să verificați disponibilitatea rețelei. Alamofire

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")
 }
}

Utilizați acest lucru pentru a informa utilizatorul sau pentru a amâna cererile. Pentru modele mai avansate, ia în considerare combinarea accesibilității cu un mecanism de rejudecare, cum ar fi rejudecarea cererilor eșuate atunci când conectivitatea este restabilită.

Cele mai bune practici pentru crearea de rețele de producție-rețea

Urmând modele stabilite va menține stratul de rețea menține, sigur și performant.

1. Adoptarea modelelor codabile

Defineşte întotdeauna tipuri Swift care sunt conforme cu (sau ) pentru a răspunde la parsing. Aceasta elimină manipularea manuală JSON şi reduce bug-urile. Utilizaţi sau nivelul inferior dacă aveţi nevoie de conţinut dinamic. Apple Ghid codabil acoperă cartografierea avansată cu chei personalizate.

2. Autentificare mai sigură și gestionarea jetoanelor

Nu hardcode tastele sau jetoanele API. Păstrați valori sensibile în Keychain și atașați-le la cereri prin antetul . Pentru fluxurile OAuth, implementați un interceptor de reîmprospătare jeton. Protocolul Alamofire vă permite să retrimiteți automat cererile după obținerea unui nou jeton. Schelet de probă:

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. Conexiune cu asinc/await

Alamofire 5 suportă pe deplin modelul Swift . Utilizați ] versiuni ale metodelor de solicitare pentru a scrie mai curat, cod liniar:

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

Combinați acest lucru cu convaility structurat (grupuri de sarcini, actori) pentru a gestiona mai multe cereri și pentru a evita apelul înapoi iad.

4. Implementează caching

Pentru a reduce apelurile de rețea și a îmbunătăți sprijinul offline, configurați politicile de cache. Alamofire respectă (de exemplu, . De asemenea, puteți folosi un personal cu o capacitate de disc adecvată:

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. Testați-vă nivelul de rețea

Scrieți teste de unitate pentru clienții API folosind date simulate. Alamofire ] poate fi injectat cu un protocol simulat care returnează răspunsuri predefinite. Luați în considerare utilizarea bibliotecilor ca sau abstractia încorporat . Testarea asigură manipularea erorilor și logica de parsare sunt corecte fără a lovi obiective reale.

6. Utilizați un administrator de rețea centralizat

Creați o singură clasă care configurează o instanță cu URL de bază, antete, interceptoare și un cache comun. Aceasta previne suprapunerea și face ușor de schimbat politici sau să râdă de întregul strat. Exemplu:

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
 }
}

Pentru o înțelegere cuprinzătoare a modelelor de rețea, consultați Alamofire Documentație avansată privind utilizarea .În plus, REST API tutorial la restfulapi.net oferă perspective valoroase în proiectarea API robuste.

Prin respectarea acestor orientări și pârghie Alamofire API expresive, puteți construi un strat de rețea, care este atât de puternic și ușor de menținut. Biblioteca abstractizează multe dintre aspectele plictisitoare de încărcare URL-ului oferindu-vă în același timp un control complet atunci când aveți nevoie de ea.