Table of Contents
Alamofire 시작하기
iOS 프로젝트로 Alamofire를 통합하려면 Swift Package Manager, CocoaPods 또는 Carthage를 사용하여 라이브러리를 추가할 수 있습니다. Swift Package Manager는 Xcode로 구축 된 것과 같은 권장된 접근법입니다. File] → Add Packages를 추가하고 저장소 URL 을 입력하면 됩니다. ]파일]을 추가하면, 네트워크가 연결되는 경우, 네트워크가 연결됩니다.
import Alamofire
Alamofire의 별명으로는 모든 일반적인 HTTP 운영에 편리한 항목 지점을 제공합니다. 후드 아래에는 Apple의 를 사용하지만, 큐 관리, 매개 변수 인코딩 및 응답 검증과 같은 보일러 플레이트를 요약합니다. 이것은 네트워킹 배관보다 오히려 비즈니스 논리에 초점을 맞추고 있습니다. 아래 네트워킹 층에 대한 자세한 내용은 Apple의 URL[FLT][FLT]]]]]]]]]]]]]]]]
수행 GET 요청
RESTful endpoint의 데이터는 가장 일반적인 작업입니다. Alamofire는 요청을 concise 및 읽기를 할 수 있습니다. 다음 예제는 hypothetical 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)")
}
}
]의 사용을 공지합니다. Swift의 ] 프로토콜을 모델 객체로 자동 파싱합니다. ]를 ]에 따르는 구조로 정의합니다. (또는 ]). 이 접근법은 수동 JSON 직렬화를 제거하고 유형 안전을 향상시킵니다.
Query 매개 변수 및 헤더 추가
많은 REST APIs는 쿼리 매개 변수 또는 사용자 정의 HTTP 헤더를 요구합니다. Alamofire는 사전 및 처리로 매개 변수를 허용하고 자동적으로 GET 요청 (parameters는 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 인코딩 매개 변수를 호출하고 요청 URL에 첨부합니다. 사용자 정의 인코딩을 위해 예시를 지정할 수 있습니다. 예를 들어 ]].
응답 검증
] 메소드는 200-299 범위의 HTTP 상태 코드에 대한 자동 검사 및 비 허용 콘텐츠 유형과 응답을 거부합니다. 또한 사용자 정의 유효성 기준을 추가 할 수 있습니다. 예를 들어, 200 및 201 상태 코드 만 허용 :
.validate(statusCode: [200, 201])
유효성 검사 실패는 응답 핸들러에 있는 오류로 보고됩니다. 애플리케이션 전체에 일관성 있는 오류 처리를 구현할 수 있습니다.
POST 데이터 전송
일반적으로 POST 요청체를 필요로 하는 리소스를 생성하거나 업데이트하는 것은 일반적으로 요청체를 요청해야 합니다. Alamofire는 REST API에 가장 일반적인 점이 있는 와 여러 인코딩 전략을 지원합니다. 다음 예제는 서버의 새로운 사용자 객체를 보냅니다.
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 토큰 교환)을 기대한다면, 대신 를 사용하십시오. 파일 업로드 또는 혼합 데이터의 경우 Alamofire는 멀티 파트 요청을 구성하는 를 제공합니다. 예:
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 APIs는 종종 PUT (전체 업데이트), PATCH (부분 업데이트) 및 DELETE (removal) 작업을 필요로합니다. Alamofire는 같은 메소드와 함께 이러한 핸들을 처리합니다. 간단히 매개 변수를 변경합니다.
PUT 및 PATCH의 특징
기존 리소스를 업데이트하려면 또는 ]를 사용하십시오. 요청 본문은 업데이트 된 필드를 포함합니다.
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 No Content).
고급 오류 처리 및 네트워크 모니터링
로버스트 오류 처리는 원활한 사용자 경험에 중요한 것입니다. Alamofire는 네트워크 오류 (시간 아웃, 연결 없음), 서버 오류 (배신 상태 코드) 및 직렬화 실패 (무효한 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의 ] 모니터 연결 변경. 앱 수명주기에서 초기 모니터링 시작:
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")
}
}
이 기능을 사용하여 사용자 또는 우편 요청을 알려줍니다. 더 고급 패턴을 위해 연결이 복원 될 때 재량 메커니즘과 같은 재량 메커니즘과의 연결성을 결합 고려하십시오.
생산-Ready Networking을위한 모범 사례
설치 패턴을 따라 네트워크 레이어 유지, 보안 및 실행을 유지 합니다.
1. Codable 모형을 채택합니다
항상 ] (또는 ]) 응답 패싱에 따라 스위프트 유형 정의. 이 수동 JSON 조작을 제거하고 버그를 감소. 사용 또는 낮은 ‐ 수준 동적 콘텐츠를 필요로하는 경우. 애플의 사용 가이드] 사용자 정의 키로 고급 맵핑을 다룹니다.
2. Safer 인증 및 토큰 관리
API 키 또는 토큰을 절대로 하드 코드하지 마십시오. 키 체인의 민감한 값을 저장하고 ] 헤더를 통해 요청할 수 있습니다. OAuth 흐름을 위해 토큰을 새로 고침 인터셉터를 구현합니다. Alamofire의 ] 프로토콜은 새로운 토큰을 얻기 후에 자동으로 재량 요청을 허용합니다. 샘플 스켈레톤 :
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를 가진 Concurrency
Alamofire 5는 Swift의 concurrency 모델을 완벽하게 지원합니다. ]]를 사용하여, 선형 코드를 작성하는 요청 방법의 버전:
do {
let users = try await AF.request("https://api.example.com/users")
.serializingDecodable([User].self)
.value
print("Users: \(users)")
} catch {
print("Error: \(error)")
}
여러 요청을 관리하고 콜백 지옥을 피하기 위해 구조화 된 concurrency (task groups, actors)와 이것을 결합합니다.
4. 캐싱 구현
네트워크 통화를 줄이고 오프라인 지원을 개선하기 위해 캐싱 정책을 구성하십시오. Alamofire는 ] (예 : ]])를 존중합니다. 또한 적절한 디스크 용량으로 사용자 정의 를 사용할 수 있습니다.
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 클라이언트를 위한 단위 테스트를 작성합니다. Alamofire의 ]는 사전 정의된 응답을 반환하는 모성 프로토콜로 주입할 수 있습니다. 또는 내장 요약과 같은 라이브러리를 사용하여 고려하십시오. 테스트는 오류 처리와 패싱 논리를 보장하는 것은 실제 엔드포인트를 타격하지 않고 정확합니다.
6. 중앙화된 네트워킹 매니저를 사용하십시오
단일 ] 클래스를 작성하는 기본 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]는 강력한 API를 설계하는 귀중한 통찰력을 제공합니다.
Alamofire의 표현 API를 활용한 가이드라인과 레버리지를 따라, 강력한 유지가 용이하고 쉽게 네트워크 레이어를 구축할 수 있습니다. 라이브러리는 필요한 경우 URL 로딩의 다양한 측면을 요약하고, 필요한 경우 전체 컨트롤을 제공합니다.