반응형
Notice
Recent Posts
Recent Comments
Link
- Today
- Total
04-15 12:01
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- r
- 딥러닝
- HTTP
- Observable
- barplot
- rest api
- 오블완
- MVC
- cocoapods
- scheduledTimer
- 시각화
- decode
- Optional
- rxswift
- SQL
- ios
- tapply
- Linux
- 티스토리챌린지
- Python
- SWIFT
- 연산자
- ReLU
- deeplearning
- swiftUI
- substr
- 명령어
- struct
- Request
- sigmoid
Archives
iOS 개발 기록 블로그
REST API를 RxSwift+Moya 환경과 접목하여 알아보자 본문
반응형
RxSwift와 Moya를 사용하여 REST API를 처리하고 있다면,
REST API에 대한 이해를 iOS 개발 관점에서 더 심화하는 것이 좋습니다.
이를 위해 아래의 주제들을 알아두면 더욱 효과적으로 개발할 수 있습니다.
1. Moya와 REST API의 연계
Moya는 네트워크 계층을 관리하는 데 강력한 라이브러리로, REST API를 RxSwift와 결합하여 비동기적인 방식으로 사용할 수 있습니다. 다음은 알아두면 좋은 Moya 활용 관련 지식입니다:
Moya의 기본 구조 이해
- TargetType을 정의하여 API의 엔드포인트를 명확히 관리:
enum MyAPI {
case fetchUsers
case createUser(name: String, email: String)
}
extension MyAPI: TargetType {
var baseURL: URL { URL(string: "<https://api.example.com>")! }
var path: String {
switch self {
case .fetchUsers: return "/users"
case .createUser: return "/users"
}
}
var method: Moya.Method {
switch self {
case .fetchUsers: return .get
case .createUser: return .post
}
}
var task: Task {
switch self {
case .fetchUsers: return .requestPlain
case .createUser(let name, let email):
return .requestParameters(
parameters: ["name": name, "email": email],
encoding: JSONEncoding.default
)
}
}
var headers: [String: String]? {
return ["Content-Type": "application/json"]
}
}
RxSwift와 Moya의 결합
- Moya에서 RxSwift를 통해 비동기 요청 처리:
let provider = MoyaProvider<MyAPI>()
provider.rx.request(.fetchUsers)
.map([User].self) // User는 Codable을 준수
.subscribe(onSuccess: { users in
print("Fetched users: \\(users)")
}, onError: { error in
print("Error: \\(error)")
})
.disposed(by: disposeBag)
에러 처리
- HTTP 상태 코드 및 서버 응답을 통해 에러를 분류하고 처리:
provider.rx.request(.fetchUsers)
.filterSuccessfulStatusCodes() // 200-299 상태 코드만 허용
.subscribe(onSuccess: { response in
print("Success: \\(response)")
}, onError: { error in
if let moyaError = error as? MoyaError {
switch moyaError {
case .statusCode(let response):
print("Status Code Error: \\(response.statusCode)")
default:
print("Other Error: \\(moyaError.localizedDescription)")
}
}
})
.disposed(by: disposeBag)
2. REST API 특화 지식
RxSwift와 Moya를 잘 활용하려면 REST API의 특성을 더 깊이 이해하는 것이 중요합니다.
API Rate Limiting
- 일부 API는 요청 빈도를 제한합니다. 이를 처리하기 위해:
- 서버에서 429 Too Many Requests 상태 코드를 반환하는지 확인.
- 클라이언트에서 요청을 제한하려면 RxSwift의 throttle 연산자를 활용:
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.throttle(.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: { _ in
provider.rx.request(.fetchUsers).subscribe().disposed(by: disposeBag)
})
.disposed(by: disposeBag)
Pagination 처리
- REST API에서 대량의 데이터를 효율적으로 가져오기 위해 페이징 처리가 필요합니다.
- 보통 쿼리 파라미터로 페이지 정보를 전달:
enum MyAPI {
case fetchUsers(page: Int)
}
extension MyAPI: TargetType {
var task: Task {
switch self {
case .fetchUsers(let page):
return .requestParameters(
parameters: ["page": page],
encoding: URLEncoding.default
)
}
}
}
- RxSwift를 사용한 페이징 처리 로직:
var currentPage = 1
func fetchNextPage() {
provider.rx.request(.fetchUsers(page: currentPage))
.map([User].self)
.subscribe(onSuccess: { users in
self.currentPage += 1
self.users.append(contentsOf: users)
})
.disposed(by: disposeBag)
}
Retry 및 백오프 전략
- 네트워크 요청 실패 시 재시도를 구현:
provider.rx.request(.fetchUsers)
.retry(3) // 3회 재시도
.subscribe(onSuccess: { response in
print("Success after retries")
}, onError: { error in
print("Request failed after retries")
})
.disposed(by: disposeBag)
- 지수 백오프(Exponential Backoff) 적용:
provider.rx.request(.fetchUsers)
.retryWhen { errors in
errors.enumerated().flatMap { attempt, error -> Observable<Int> in
let delay = pow(2.0, Double(attempt))
return Observable<Int>.timer(.seconds(Int(delay)), scheduler: MainScheduler.instance)
}
}
.subscribe()
.disposed(by: disposeBag)
3. iOS에서 REST API 활용을 위한 최적화
Codable 활용
- API 응답을 Codable로 매핑하여 간결한 모델 관리:
struct User: Codable {
let id: Int
let name: String
let email: String
}
provider.rx.request(.fetchUsers)
.map([User].self)
.subscribe(onSuccess: { users in
print("Fetched users: \\(users)")
})
.disposed(by: disposeBag)
네트워크 모니터링
- 네트워크 연결 상태를 체크하여 적절한 사용자 피드백 제공:
- Reachability 또는 Network.framework를 사용.
Response Caching
- 데이터 요청을 최소화하기 위해 캐싱 사용:
- URLSession의 URLCache를 활용하거나 Moya의 커스텀 플러그인으로 캐싱 구현.
로컬 데이터와 동기화
- RxSwift와 CoreData 또는 Realm을 결합해 API 응답 데이터를 로컬 저장소와 동기화.
4. 비동기 작업과 UI의 연계
메인 스레드 처리
- REST API 호출 후 UI 업데이트는 메인 스레드에서 수행:
provider.rx.request(.fetchUsers)
.observe(on: MainScheduler.instance)
.subscribe(onSuccess: { users in
self.tableView.reloadData()
})
.disposed(by: disposeBag)
데이터 바인딩
- RxCocoa를 사용해 REST API 데이터를 UI와 바인딩:
provider.rx.request(.fetchUsers)
.map([User].self)
.bind(to: tableView.rx.items) { tableView, index, user in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: IndexPath(row: index, section: 0))
cell.textLabel?.text = user.name
return cell
}
.disposed(by: disposeBag)
5. 실시간 기능
RxSwift를 통해 REST API와 WebSocket 또는 SSE(Server-Sent Events) 같은 실시간 데이터를 조합하는 방식도 알아두면 유용합니다.
REST API 응답의 상태를 Rx 관찰 가능한 형태로 가공해서 활용해보면 좋습니다.
이 실시간 기능도 나중에 자세히 더 공부해보려고 합니다. 처음 보는 것들이라 ㅎㅎ

반응형
'Back-end' 카테고리의 다른 글
Java, Spring 프레임워크 기초와 IoC, DI의 개념과 iOS 관련 예시로 이해하기 (1) | 2024.11.29 |
---|---|
REST API 이해하기 (iOS URLSession 사용 예시 포함) (0) | 2024.11.18 |
HTTP/1.1은 무엇일까? (0) | 2024.11.17 |
HTTP의 정의, 기본 작동 원리, 요청/응답 구조, HTTP/HTTPS (1) | 2024.11.17 |
오블완 챌린지 기념 iOS 개발자 서버 개발 찍먹 (5) | 2024.11.15 |