Combine 실습 3

yongbeom kwak·2022년 7월 25일
0

Combine

목록 보기
4/5

목표

  1. 서버로부터 받은 JSon을 가져온 데이터와 Combine을 사용하여 구독한다

  2. UrlSession 작업을 Alamofire로 변경해본다.

Url 정보


enum API{
    case fetchTodos
    case fetchPosts
    
    var url: URL{
        
        switch self {
        case .fetchPosts: return URL(string: "https://jsonplaceholder.typicode.com/posts")!
        
        case .fetchTodos: return URL(string: "https://jsonplaceholder.typicode.com/todos")!
        }
    }
}

Servcie function

enum ApiService {
    
    
    ///  Todos 가져오기
    /// - Returns: AnyPublisher<[Todo], Error>
    static func fetchTodos() -> AnyPublisher<[Todo], Error> {
        
        return URLSession.shared.dataTaskPublisher(for: API.fetchTodos.url)
            .map{$0.data}
            .decode(type: [Todo].self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
	}
}

ViewModel

import Foundation
import Combine

class ViewModel: ObservableObject {
    
    var subscriptions = Set<AnyCancellable>()
    
    
    
    func fetchTodos(){
        
        ApiService.fetchTodos()
            .sink { completion in
                
                switch completion {
                case .failure(let err):
                    print("\(err)")
                case .finished:
                    print("Finish")
                }
                
            } receiveValue: { (todos: [Todo]) in
                print("todos count \(todos.count)")
            }.store(in: &subscriptions)
        
    }
}

View

import SwiftUI
import CoreData

struct ContentView: View {
    
    @StateObject var viewModel:ViewModel
    
    init(){
        self._viewModel = StateObject.init(wrappedValue: ViewModel())
        
        //StateObject는  _(언더바)를 붙혀서 초기화를 해줘야함, bind과 같음
        
    }
    
    var body: some View {
        
        VStack{
            Button {
                self.viewModel.fetchTodos()
            } label: {
                Text("Todos 호출").foregroundColor(.white)
            }
            .padding()
            .background(RoundedRectangle(cornerRadius: 10).fill(.gray))
 }

UrlSession -> AF


import Foundation
import Combine
import Alamofire

enum ApiService {
    
    
    ///  Todos 가져오기
    /// - Returns: AnyPublisher<[Todo], Error>
    static func fetchTodos() -> AnyPublisher<[Todo], Error> {
        
        
        //AF로 Refactor
        return AF.request(API.fetchTodos.url)
            .publishDecodable(type: [Todo].self) //디코딩
            .value() // 값만 가져오기
            .mapError { (afError:AFError) in
                //.value를 거치면 AnyPublisher<Value, AFError> 상태이므로 AFError -> Error로 캐스팅
                return afError as Error
            }
            .eraseToAnyPublisher()
        

    }
}

정리

Alamofire

Alamofire는 swift를 기반으로 한 HTTP 네트워킹 라이브러리이다. 이는 공통적인 네트워크 작업을 함에 있어 매우 우아한 인터페이스를 제공한다.

  1. chainable request/response methods
  2. JSON, Codable decoding
  3. authentication
profile
IOS개발 공부생

0개의 댓글