ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] Network connect 두 가지 방법
    iOS💖 2024. 10. 22. 15:44

    Network 연결하기

    1. url 에 필요한 리소스 
      • base
      • path
      • params
      • header
    2. URLComponents에 ⬅️ 만들어진 url 리소스 넣기
    3. URLQueryItems에 넣을 쿼리 파라매터(params) 들 추가하기 
    4. URLRequest 만들기 ⬅️ URLComponents.url 넣기
    5. header 요소들, forEach 문으로 ➡️ URLRequest에 .addValue하여 넣기

     

    리팩토링 하기 전

    let base = "https://api.github.com/"
    let path = "user/\(keyword)"
    let params: [String:String] = [:]
    let header: [String:String] = ["Content-Type": "application/json"]
    
    let urlComponent = URLComponents(string: base + path)
    let queryItems = params.maps { (key: String, value: String) in
        return URLQueryItems(name: key, value: value)
    }
    urlComponent.queryItems = queryItems
    
    var request = URLRequest(url: urlComponent.url!)
    
    header.forEach{ (key: String, value: String) in
        request.addValue(value, forHTTPHeaderField: key)
    }
    
    URLSession.shard
        .dataTaskPublisher(for: request)
        .tryMap{ (data: Data, response: URLResponse) -> Data in // error처리: tryMap(o)
            guard let response = response as? HTTPURLResponse,
                (200..<300).contains(response.statusCode) else {
                let response = response as? HTTPURLResponse
                let statusCode = response.statusCode ?? -1
                throw NetworkError.responseError(statusCode: statusCode)
            }
            return data
        .decode(type: UserProfile.self, decode: JSONDecoder())
        .receive(on: Runloop.main)
        .sink{ completion in
            switch completion {
            case .failure(let error)
                self.user = nil
            case .finished: break
            }
        }.store(in: &subscriptions)

     

     

     

    리팩토링 후

    • network 연결에 필요한 url resources 들을 만들어서 ➡️ load() 에 넣어준다.
    • load() 에서는, urlRequest를 뽑아서, session에 넣고, dataTask 를 만들어 ➡️ publisher 을 return 한다.
    • Resource 는 UserProfile 을 받기 위한 resource이니, 타입은 <UserProfile> 이다.
    let network = NetworkService(configuration: .default)
    
    // Resource
    let resource = Resource<UserProfile>(
        base: "https://api.github.com/",
        path: "users/\(keyword)",
        params: [:],
        header: ["Content-Type":"application/json"])
    
    // NetworkService
    network.load(resource)
        .receive(on: Runloop.main)
        .sink{ completion in
            switch completion {
            case .failure(let error):
                self.user = nil
            case .finished: break
            }
        } receiveValue: { user in
            self.user = user
        }.store(in: &subscrptions)

    댓글

Designed by black7375.