Alamofire + Combine 사용
소개
최근, iOS 개발, SwiftUI 의 공부를 하고 있습니다만, WebAPI 의 호출을 하기 위해 Alamofire 를 선정했습니다.
비동기 처리에서는 Alamofire + RxSwift 등을 사용하는 것이 일반적인 것 같습니다만, Alamofire 5.2.0 에서 Apple제의 비동기 라이브러리 Combine 가 서포트되었으므로, Alamofire + Combine 를 시도해 보았습니다.
도서관 등
Xcode : 12.4
Alamofire : 5.4.1
샘플 앱
샘플 앱으로 ChatWork API 토큰을 TextField에 입력하고 값을 얻을 수 있으면 이름에 이름을 설정하여 표시하는 최소한의 앱을 만들었습니다.
WebAPI는 Chatwork API의 /me을 사용합니다.
구현
LoginViewModel.swift
import Foundation
import Combine
import Alamofire
class LoginViewModel: ObservableObject {
private var disposeBag = Set<AnyCancellable>()
@Published var token = ""
@Published var name = "name"
func getMe() {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
AF.request("https://api.chatwork.com/v2/me", headers: ["X-ChatWorkToken": token])
.publishDecodable(type: MeModel.self, decoder: decoder)
.sink { data in
guard let me = data.value else {
print("error")
return
}
print(me.name)
print(me.accountId)
self.name = me.name
}.store(in: &disposeBag)
}
}
.publishDecodable(type: MeModel.self, decoder: decoder)
DataResponsePublisher를 반환하므로 Combine에서 처리할 수 있습니다.Chatwork API의 응답은 key가 뱀 케이스
account_id
이지만 Swift에서는 낙타 케이스 accountId
이므로,decoder.keyDecodingStrategy = .convertFromSnakeCase
에서 변환하도록 지정합니다.Decodable을 구현한 데이터 모델 정의
자신의 정보를 나타내는 데이터 모델은 다음과 같이 정의했습니다.
데이터 정의 MeModel.swift
MeModel.swift
import Foundation
struct MeModel: Decodable {
var accountId: Int
var roomId: Int
var name: String
var chatworkId: String
var organizationId: Int
var organizationName: String
var department: String
var title: String
var url: String
var introduction: String
var mail: String
var telOrganization: String
var telExtension: String
var telMobile: String
var skype: String
var facebook: String
var twitter: String
var avatarImageUrl: String
var loginMail: String
}
참고로 UI의 정의는 이런 느낌입니다.
UI 정의 ContentView.swift
MeModel.swift
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel = LoginViewModel()
var body: some View {
NavigationView {
VStack(alignment: .center) {
VStack(alignment: .leading) {
Text("Token")
TextField("token", text: $viewModel.token, onCommit: {
})
.keyboardType(.alphabet)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
Text(viewModel.name)
}
.padding(10)
Divider()
Button("Get") {
viewModel.getMe()
}
.padding()
}
.overlay(RoundedRectangle(cornerRadius: 5).stroke())
.padding(.horizontal, 50)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Moya는 Combine을 지원하지 않습니다.
덧붙여서, Alamofire를 보다 간단하게 이용하기 위한 모야 라고 하는 라이브러리가 있습니다만, 14.0.0 에서는 Combine 에는 아직 대응하고 있지 않습니다.
14.0.0 베타에서 한 번 소개되었지만 문제가 있고 출시 전에 사라진 것 같습니다..
Reference
이 문제에 관하여(Alamofire + Combine 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ikeda_shogouki/items/01d6eea71f5bde826930텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)