개발/Swift

Swift 네트워크 구조 잡기

덤벨로퍼 2024. 4. 8. 15:47

기본적인 구조는 APIClient, Request, Service가 있다.

APIClient 객체가 있다. APIClient 는 alamofire를 직접 호출하는 역할을 한다.

api호출에 공통적인 로직이 있는경우 처리에 포함시켜주면 중복코드를 막을수 있다.

let response = await manager.request(request.url, method: request.method,
                                 parameters: request.parameters, encoding: request.encoding,
                                 headers: request.headers)
.validate()
.serializingData()
.response

/// 실패 처리 ( 성공은 생략 ) 
case let .failure(error):

if statusCode == 401 && isRefreshIfNeeded {
	//refreshToken
  switch await refreshAccessToken() {
  case .success:
      return await requestAPI(request: request, uuid: uuid, isRefreshIfNeeded: false)
  case let .failure(error):
      return .failure(error)
  }
} else {

  let error = Error(uuid: uuid, code: statusCode, error: error)
  AnalyticsHelper.shared.logError(error)
  return .failure(error)
}
}

 

Request 객체는 api 호출시에 필요하다 url, header, parameter 등

api request 함수에 필요한 내용들을 담고있다.

구현체는 따로 있고 구현체에서 디폴트한 값은 지정해주어 중복 코드를 방지하였다.

해당 Request 구현체는 API 호출때마다 생성해서 넣어준다. 

public protocol RequestProtocol {
    var url: String { get }
    var method: HTTPMethod { get }
    var parameters: Parameters? { get }
    var headers: Headers? { get }
    var encoding: ParameterEncoding { get }
}

 

Service 객체가 있다 Service 객체는 Request 객체를 생성 + APIClient를 통해 네트워크를 호출한다.

백엔드 service 레이어가 분리 되어있는경우나 기능적인 분류를 통해 각 각의 Service 클래스를 만들어 사용하였다.

ex> OrderService, UserService ... 

 public init(gDB: DatabaseProtocol) {
        self.apiClient = APIClient(gDB: gDB)
    }
 //사용
 let request = Request(url: "users/" + userIdentifier + "/friends",
                              method: .get, parameters: parameters)
  let response = await apiClient.requestAPI(request: request, uuid: uuid)
  
  //이후 성공 실패 처리