- This topic has 0개 답변, 1명 참여, and was last updated 4 years, 7 months 전에 by iJoom.
0 답변 글타래를 보이고 있습니다
-
글쓴이글
-
-
iJoom참가자
- 글작성 : 8
- 답글작성 : 1
통신: Moya
- Moya = urlSession , Alamofire를 한번더 감싼 통신 api 입니다.
- 여행 데이터를 통신하고 보여주는 뷰에서 Moya를 활용해 통신을 해보았습니다.
- 메소드의 분기처리 및 개별로 get , post를 설정해줄 수 있어서 편했습니다.
struct BaseResponseModel<Decode: Decodable>: Decodable { let status: Int let data: Decode? let success: Bool let message: String? }
- 데이터 통신 분기처리를 위한 모델 생성
final class APIService { static let shared = APIService() private init() {} private let provider = MoyaProvider<APITarget>() func requestCityActivity(cityID: Int, completion: @escaping (Result<CityActivityResponseModel, Error>) -> Void) { provider.request(.cityActivity(cityID: cityID)) { result in switch result { case let .success(success): let responseData = success.data do { let decoded = try JSONDecoder().decode(CityActivityResponseModel.self, from: responseData) completion(.success(decoded)) } catch { completion(.failure(error)) } case let .failure(error): completion(.failure(error)) } } } }
- Activity Data 통신을 위한 APIService 메소드 정의
typealias CityActivityResponseModel = BaseResponseModel<[_CityActivityResponseModel]>- typealias를 이용한 제네릭 모델 별칭 지정, 코드 간소화 및 가독성 개선
@escaping (Result<CityActivityResponseModel, Error>)
- Generic 부분 추가 설명 , 하나 이상의 타입 인자를 사용할 수 있으며, 꺽쇠 안에서 타입 인자 이름을 콤마로 분리하여 작성한다. (ex. <T, M>)
- Result 의 원래 인자는 <Success, Failure>
public protocol TargetType { /// The target's base `URL`. var baseURL: URL { get } /// The path to be appended to `baseURL` to form the full `URL`. var path: String { get } /// The HTTP method used in the request. var method: Moya.Method { get } /// Provides stub data for use in testing. var sampleData: Data { get } /// The type of HTTP task to be performed. var task: Task { get } /// The type of validation to perform on the request. Default is `.none`. var validationType: ValidationType { get } /// The headers to be used in the request. var headers: [String: String]? { get } } public extension TargetType { /// The type of validation to perform on the request. Default is `.none`. var validationType: ValidationType { return .none } }
- Moya의 TargetType protocol 을 상속받아서 열거형으로 APITarget구현
// import Moya enum APITarget: TargetType { case medianHotelRead(cityID: Int, subCategory: Int) case cityActivity(cityID: Int) case tripCreate(cityID: Int, body: TripCreateRequestModel) case medianFoodRead(cityID : Int) var baseURL: URL { return URL(string: "http://13.125.42.117:3000")! } var path: String { switch self { case let .medianHotelRead(cityID, subCategory): return "/median/\(cityID)/\(subCategory)/hoteliOS/" case let .cityActivity(cityID): return "/citys/\(cityID)/Activity" case let .tripCreate(cityID, _): return "/trips/\(cityID)" case let .medianFoodRead(cityID): return "/median/\(cityID)/food" } } // Moya의 method가 모야의 쉬우면서 편한 기능이라고 생각합니다. // 각 메소드가 get인지 post인지 일일이 설정이 가능하며, 협업시 각 메소드의 기능들을 보기 쉽게 구별할 수 있어서 코드의 가독성 또한 좋아집니다. var method: Method { switch self { case .medianHotelRead: return .get case .cityActivity: return .get case .tripCreate: return .post case .medianFoodRead: return .get } // case. sendA: // return .post } var sampleData: Data { return .init() } var task: Task { switch self { case .medianHotelRead: return .requestPlain case .cityActivity: return .requestPlain case let .tripCreate(cityID, body): let encoded = try! JSONEncoder().encode(body) return .requestCompositeData(bodyData: encoded, urlParameters: ["CityId": cityID]) case let .medianFoodRead(cityID): return .requestPlain } } var headers: [String : String]? { return ["Content-Type": "application/json"] } }
enum APITarget: TargetType { case medianHotelRead(cityID: Int, subCategory: Int) case cityActivity(cityID: Int) case tripCreate(cityID: Int, body: TripCreateRequestModel) case medianFoodRead(cityID : Int) var path: String { switch self { case let .cityActivity(cityID): return "/citys/\(cityID)/Activity" } }
func requestCityActivity(cityID: Int, completion: @escaping (Result<CityActivityResponseModel, Error>) -> Void) { provider.request(.cityActivity(cityID: cityID))
- provider.request부분에서 .cityActivity부분이 APItarget을 사용 하는부분
- provider.request( APITarget.cityActivity(cityID: cityID)) 축약형으로 표현
override func viewDidAppear(_ animated: Bool) { let cityID = 1 APIService.shared.requestCityActivity(cityID: cityID) { [weak self] result in switch result { case let .success(success): guard let data = success.data else { return } self?.responseModel = data case let .failure(error): print(error.localizedDescription) } } }
- viewDidAppear ViewLifeCycle에서 APIService의 분기별로 처리해 놓은 (싱클턴패턴) 정의 해놨던 request 함수호출
2020-03-28 오후 4:32 #4873
-
-
글쓴이글
0 답변 글타래를 보이고 있습니다
- 답변은 로그인 후 가능합니다.