SwiftUIでCombineを使用してAPIを叩くとき
URLSession.shared.dataTaskPublisher
を使用する場合は多々あると思います。
とあるアプリを作成中(MVVCを導入)ViewModel内でdataTaskPublisherの処理を書くとどうしてもコードが長くなってしまうので共通化できるところを共通化したお話です。
私の場合はURLRequestを生成する部分はNetworkというClassを作成しそこにある程度処理を持たせています。
下記のコードのようにdecodingTypeとURLRequestを引数に持たせることによって今のところ問題なく使えています。
func sinkCompletion
の方もSubscrivers.Completionを引数に渡すことによってswitch文をviewmodelの関数に書く必要がなくなります。
sample.swift
func urlSession<T: Decodable>(with request: URLRequest, decodingType: T.Type) -> AnyPublisher<T, Error> {
URLSession.shared.dataTaskPublisher(for: request)
.tryMap{(data, response) -> Data in
guard let response = response as? HTTPURLResponse,
// 処理
else {
throw URLError(.badServerResponse)
}
return data
}
.decode(type: T.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
sample2.swift
func sinkCompletion(res: Subscribers.Completion<Error>) {
switch res {
case .finished:
print("Completion:\(res)")
break
case .failure:
print("Completion:\(res)")
break
}
}