본문으로 바로가기

[iOS] URLSession을 활용한 NetworkService 구현

category iOS 2022. 7. 23. 13:12
728x90

사용 함수

  •  URLSessionConfiguration
    • .default: 기본 작업
    • .ephemeral: 보안 작업
    • .background: 다운로드 작업
  • URLSession
    • URLSessionDataTask
  • URLSessionTask
    • dataTask
    • uploadTask
    • downloadTask
// 예시
import Foundation

let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)

let url = URL(string: /*"https://..."*/)!
let task = session.dataTask(with: url) { data, response, error in
    quard let httpResponse = response as? HTTPURLResponse,
        (200..<300).contains(httpResponse.statusCode) else {
        return
    }
    
    guard let data = data else { return }
    let result = String(data: data, encoding: .utf8)
}

task.resume()
  • Codable: JSON 인/디코더
// 예시
do {
    let decoder = JSONDecoder()
    let data = try decoder.decode(/*Codable Structure*/, from: data)
} catch let error as NSError {
    print("\(error)")
}
// Network Service Class

import Foundation
import Combine

///// Defines the Network service errors.
enum NetworkError: Error {
    case invalidRequest
    case invalidResponse
    case responseError(statusCode: Int)
    case jsonDecodingError(error: Error)
}

final class NetworkService {
    let session: URLSession
    
    init(configuration: URLSessionConfiguration) {
        session = URLSession(configuration: configuration)
    }
    
    func load<T>(_ resource: Resource<T>) -> AnyPublisher<T, Error> {
        guard let request = resource.urlRequest else {
            return .fail(NetworkError.invalidRequest)
        }
        
        return session
            .dataTaskPublisher(for: request)
            .tryMap { result -> Data in
                guard let response = result.response as? HTTPURLResponse,
                      (200..<300).contains(response.statusCode)
                else {
                    let response = result.response as? HTTPURLResponse
                    let statusCode = response?.statusCode ?? -1
                    throw NetworkError.responseError(statusCode: statusCode)
                }
                return result.data
            }
            .decode(type: T.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }
}
728x90