Table of Contents
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.