Merhabalar bu yazımda Combine ile iOS uygulamalarınızda servis isteklerini nasıl yönetip kullanabileceğinizi paylaşacağım.
Bu işlem için URLSession üzerinden publish işlemi yapacağız. Bu işlemler içerisinde error handle, decode ve gerekli tüm işlemlerimizi gerçekleştirebiliriz. Kullanım olarak daha öncesinde Rx kullananlar için yabancı gelmeyecektir.
Aşağıda yazdığım basit bir servis isteği ve ardından gerçekleşen decode örneğini inceleyebilirsiniz.
import UIKit import Combine struct Httpbin: Decodable { var origin:String! var url:String! } enum ServiceError: Error { case bad case apiError(txt:String) } extension ServiceError: LocalizedError { var errorDescription: String? { switch self { case .bad: return "Ooops request error!" case .apiError(let str): return str } } } class ViewController: UIViewController { var requestSub:AnyCancellable? override func viewDidLoad() { super.viewDidLoad() } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { requestSub = serviceRequest() .sink(receiveCompletion: { (completion) in switch(completion) { case .finished: print("Finish") case .failure(let err): print(err.localizedDescription) } }) { (value) in print("Origin -> \(value.origin ?? "")") } } func serviceRequest() -> AnyPublisher<Httpbin, Error> { return URLSession.shared.dataTaskPublisher(for: URL(string: "https://httpbin.org/get")!) .handleEvents(receiveSubscription: { (_) in print("START") }, receiveCompletion: { (_) in print("Completed") }, receiveCancel: { print("Cancel") }) .tryMap { data, response in guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else { throw ServiceError.bad } return data } .decode(type: Httpbin.self, decoder: JSONDecoder()) .mapError { err in if let error = err as? ServiceError { return error } else { return ServiceError.apiError(txt: "Problem occurred!") } } .subscribe(on: RunLoop.main) .eraseToAnyPublisher() } }
START Origin -> 195.214.144.202, 195.214.144.202 Completed Finish
URLSession üzerinden dataTaskPublisher kullanarak publisher yazmaya başlıyoruz ve ardından dilerseniz durum eventlerini .handleEvents içerisindeki bloklara yazabilirsiniz. (loading animasyon işlemleri vs) daha sonrasında error handle edecekseniz tryMap ile blok içerisinde durumları yazıyorsunuz. Sonrasında aynı blok içerisinden dönen veriyi .decode ile hızlı bir şekilde uygun Decodable yapımıza decode edebiliyoruz. Seneryoda karşılaşıcak her hangi bir hata durumunda tetiklenmesi için .mapError kullanabilir ve uygun olan hatayı döndürebilirsiniz.
Thread handling operatorlerinden receive, subscribe ile zincirleri bağlayabiliyoruz. Aralarındaki kullanım farkı eğer UI ile bağlantılı bir işlem yapacaksanız .receive kullanmanız gerekir. Sonrasında .eraseToAnyPublisher ile uygun return tipimize göre son halini elde edip artık subscribe olabiliriz. Daha sonrasında .sink ile bağlanıp gerekli sonuçlara ulaşıyoruz.
İlk Yorumu Siz Yapın