Αρχίζουμε με το Αλαμόφωτο

Για να ξεκινήσετε την ενσωμάτωση του Alamofire στο έργο iOS σας, μπορείτε να προσθέσετε τη βιβλιοθήκη χρησιμοποιώντας το Swift Package Manager, CocoaPods, ή Carthage. Swift Package Manager είναι η συνιστώμενη προσέγγιση, καθώς είναι ενσωματωμένη στο Xcode. Προσθέστε το πακέτο Alamofire με πλοήγηση σε [Αρχείο → [ Προσθήκη Πακέτων[] και την είσοδο στο URL του αποθετηρίου [. Καθορίστε την έκδοση 5.0 ή αργότερα. Εναλλακτικά, αν χρησιμοποιείτε το CocoaPods, προσθέστε στο αρχείο σας και εκτελέστε . Μόλις ενσωματωθεί η εξάρτηση, εισαγάγετε το Alamofire σε οποιοδήποτε αρχείο Swift όπου χρειάζεστε τη λειτουργικότητα του δικτύου:

import Alamofire

Το ψευδώνυμο του Alamofire παρέχει ένα βολικό σημείο εισόδου για όλες τις κοινές λειτουργίες HTTP. Κάτω από το καπό, χρησιμοποιεί το της Apple αλλά αφηρημένα μακριά λεβητοστάσιο όπως διαχείριση ουράς, κωδικοποίηση παράμετρου και επικύρωση απόκρισης. Αυτό σας επιτρέπει να επικεντρωθείτε στη λογική των επιχειρήσεων και όχι να δικτύωση υδραυλικά. Για περισσότερες λεπτομέρειες σχετικά με το υποκείμενο στρώμα δικτύωσης, ανατρέξτε στην Apple's URLSsion documentation].

Εκτέλεση αιτήσεων GET

Η ανάκτηση δεδομένων από ένα τελικό σημείο RESTful είναι η πιο κοινή λειτουργία. Το Alamofire κάνει τα αιτήματα GET συνοπτικά και αναγνώσιμα. Το ακόλουθο παράδειγμα ανακτά μια λίστα χρηστών από ένα υποθετικό API:

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

Προσέξτε τη χρήση του , το οποίο αξιοποιεί το πρωτόκολλο του Σουίφτ για να αναλύσει αυτόματα τον JSON σε αντικείμενα μοντέλων. Καθορίστε μια δομή που συμμορφώνεται με ] (ή []]).

Προσθήκη παραμέτρων ερωτήματος και κεφαλίδων

Πολλές REST APIs απαιτούν παραμέτρους ερωτηματικών ή προσαρμοσμένες κεφαλίδες HTTP. Το Alamofire δέχεται παραμέτρους ως λεξικό και χειρίζεται την κωδικοποίηση αυτόματα για αιτήματα GET (παραμέτρα προσαρτώνται στο 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 αυτόματα κωδικοποιεί τις παραμέτρους και τις προσαρτά στο URL της αίτησης. Για την προσαρμοσμένη κωδικοποίηση, μπορείτε να καθορίσετε μια ρητή περίπτωση, όπως .

Επικύρωση απόκρισης

Η μέθοδος ελέγχει αυτόματα τους κωδικούς κατάστασης HTTP στο εύρος 200 ⁇ 299 και απορρίπτει τις απαντήσεις με μη αποδεκτό τύπο περιεχομένου. Μπορείτε επίσης να προσθέσετε προσαρμοσμένα κριτήρια επικύρωσης. Για παράδειγμα, να αποδεχθείτε μόνο 200 και 201 κωδικούς κατάστασης:

.validate(statusCode: [200, 201])

Οι αστοχίες επικύρωσης αναφέρονται ως σφάλματα στον χειριστή απόκρισης, επιτρέποντάς σας να υλοποιήσετε συνεπή χειρισμό σφαλμάτων καθ' όλη τη διάρκεια της εφαρμογής σας.

Αποστολή δεδομένων POST

Η Alamofire υποστηρίζει πολλαπλές στρατηγικές κωδικοποίησης, με να είναι η πιο κοινή για τα REST APIs. Το ακόλουθο παράδειγμα στέλνει ένα νέο αντικείμενο χρήστη στον εξυπηρετητή:

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

Αν το API αναμένει δεδομένα μορφής URL ⁇ κωδικοποιημένα (π.χ. για ανταλλαγή κωδίκων OAuth), χρησιμοποιήστε [[LPT:20]] αντ 'αυτού. Για αναρτήσεις αρχείων ή ανάμεικτα δεδομένα, το Alamofire παρέχει [[LFT:21]] το οποίο κατασκευάζει ένα αίτημα πολλαπλών μερών. Παράδειγμα:

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
 }

Συνεργάζεται με άλλες μεθόδους HTTP

Τα RESTful API συχνά απαιτούν PUT (πλήρης ενημέρωση), PATCH (μερική ενημέρωση), και DELETE (αποκατάσταση) λειτουργίες.Αλαμόφωτος χειρίζεται αυτές με την ίδια [[LFT:23]]] μέθοδο; απλά να αλλάξετε την [[LFT:24]] παράμετρο.

ΑΛΙΕΥΤΙΚΗ ΑΛΙΕΥΤΙΚΗ ΑΛΙΕΥΤΙΚΗ ΑΛΙΕΙΑ

Για την ενημέρωση ενός υπάρχοντος πόρου, χρησιμοποιήστε ή . Ο φορέας αίτησης περιέχει τα ενημερωμένα πεδία:

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
 }

ΔΕΛΕΤΗ

Η διαγραφή ενός πόρου συνήθως δεν απαιτεί κανένα σώμα αίτησης. Η απάντηση μπορεί να είναι κενή ή να επιστρέψει ένα μήνυμα επιβεβαίωσης:

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

Πάντα ελέγξτε την τεκμηρίωση API για τους αναμενόμενους κωδικούς κατάστασης (π.χ., 204 Χωρίς Περιεχόμενο).

Προηγμένη διαχείριση σφαλμάτων και παρακολούθηση δικτύου

Ο χειρισμός ακραίων σφαλμάτων είναι κρίσιμος για μια απρόσκοπτη εμπειρία χρήστη. Το Alamofire αναφέρει σφάλματα μέσω του [[LFT:29]] τύπου, ο οποίος διαφοροποιεί μεταξύ των σφαλμάτων δικτύου (timeout, καμία σύνδεση), των σφαλμάτων διακομιστή (κακός κώδικας κατάστασης), και των αποτυχιών σειριακής ρύθμισης (ακυρόδοξη JSON). Μπορείτε να επιθεωρήσετε το σφάλμα για να παράσχετε συγκεκριμένες πληροφορίες:

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

Ευκολότητα δικτύου

Πριν από την υποβολή των αιτήσεων, ίσως θέλετε να ελέγξετε τη διαθεσιμότητα του δικτύου. Το Alamofire [[LFT:31]] παρακολουθεί τις αλλαγές συνδεσιμότητας. Ξεκινήστε την παρακολούθηση νωρίς στον κύκλο ζωής της εφαρμογής σας:

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

Για πιο προηγμένα μοτίβα, εξετάστε το συνδυασμό προσιτότητας με έναν μηχανισμό επανέναρξης, όπως η επανέναρξη αποτυχημένων αιτήσεων όταν η συνδεσιμότητα αποκαθίσταται.

Βέλτιστες πρακτικές για την παραγωγή-έτοιμη δικτύωση

Ακολουθώντας καθιερωμένα πρότυπα θα κρατήσει το στρώμα δικτύωσης σας διατηρήσιμο, ασφαλές, και εκτελέσιμο.

1. Υιοθετήστε τα μοντέλα που μπορούν να χρησιμοποιηθούν

Πάντα να ορίζετε τύπους Swift που συμμορφώνονται με [[LFT:33]] (ή [[LFT:34]]]) για ανάλυση απόκρισης. Αυτό εξαλείφει το εγχειρίδιο χειρισμού JSON και μειώνει τα σφάλματα. Χρησιμοποιήστε [[LFT:35]]] ή το χαμηλότερο ⁇ επίπεδο [[LFT:36]] αν χρειάζεστε δυναμικό περιεχόμενο. Κωδικοποιημένος οδηγός [[LFT:1]] καλύπτει προηγμένη χαρτογράφηση με προσαρμοσμένα πλήκτρα.

2. Ασφαλέστερη ταυτοποίηση και διαχείριση σημείων

Ποτέ τα πλήκτρα API σκληρού κώδικα ή τα σημεία. Αποθήκευση ευαίσθητων τιμών στο μπρελόκ και επισυνάψτε τα σε αιτήματα μέσω της επικεφαλίδας [[LFT:37]]. Για τις ροές OAuth, εφαρμόστε ένα συμβολικό ανανεωτικό αναχαίτιση. Το πρωτόκολλο του Alamofire [[LFT:38]] σας επιτρέπει να επαναλάβετε αυτόματα αιτήματα μετά την απόκτηση ενός νέου σημείου.

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. Συμβολή με το async/await

Το Alamofire 5 υποστηρίζει πλήρως το μοντέλο concurrency του Swift. Χρησιμοποιήστε τις [[LFT:40]] εκδόσεις των μεθόδων αίτησης για να γράψετε καθαρότερο, γραμμικό κώδικα:

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

Συνδυάστε αυτό με δομημένη concurrency (ομάδες εργασίας, ηθοποιοί) για να διαχειριστείτε πολλαπλές αιτήσεις και να αποφύγετε την κόλαση callback.

4. Εφαρμογή Caching

Για να μειώσετε τις κλήσεις δικτύου και να βελτιώσετε την offline υποστήριξη, ρυθμίστε τις πολιτικές caching. Το Alamofire σέβεται το [[LFT:42]] (π.χ., [[LFT:43]]). Μπορείτε επίσης να χρησιμοποιήσετε ένα έθιμο [[LFT:44]] με κατάλληλη χωρητικότητα δίσκου:

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. Δοκιμάστε το στρώμα Δικτύωσής σας

Γράψτε τις δοκιμές μονάδων για τους πελάτες API σας χρησιμοποιώντας εικονικά δεδομένα.Αλαμόφωτος [[LFT:46]] μπορεί να εγχυθεί με ένα πρωτόκολλο mock που επιστρέφει προκαθορισμένες απαντήσεις. Σκεφτείτε χρησιμοποιώντας βιβλιοθήκες όπως [[LFT:47]] ή την ενσωματωμένη ⁇ σε [[LFT:48]] αφαίρεση. Η δοκιμή εξασφαλίζει ότι ο χειρισμός σφαλμάτων και η ανάλυση της λογικής είναι σωστές χωρίς να χτυπήσει πραγματικά τελικά σημεία.

6. Χρησιμοποιήστε έναν κεντρικό διαχειριστή δικτύωσης

Δημιουργήστε μια ενιαία τάξη που διαμορφώνει μία [[LFT:50]] περίπτωση με βασική διεύθυνση URL, κεφαλές, αναχαιτιστές, και μια κοινή μνήμη. Αυτό εμποδίζει την επικάλυψη και καθιστά εύκολη την ανταλλαγή πολιτικών ή την κοροϊδία ολόκληρου του στρώματος. Παράδειγμα:

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

Για μια ολοκληρωμένη κατανόηση των προτύπων δικτύωσης, ανατρέξτε στο Alamofire Advanced Usage documentation. Επιπλέον, το REST API tutorial at restfulapi.net προσφέρει πολύτιμες ιδέες για το σχεδιασμό ρωμαλέων APIs.

Ακολουθώντας αυτές τις οδηγίες και αξιοποιώντας το εκφραστικό API του Alamofire, μπορείτε να χτίσετε ένα στρώμα δικτύωσης που είναι τόσο ισχυρό όσο και εύκολο να διατηρηθεί.