[iOS] 모야가모야 (진짜 내가 볼라고 만드는 모야정리)

hello_hidi·2022년 12월 24일
1

아요정리방

목록 보기
5/5

음 개념은 나중에 좀 더 구체적으로 정리하고
여기서는 내가 서버통신을 할 때 어떤 순서로 차분하고 정확하게 서버통신을 해야되는지
그거에 중점을 둬서 정리하도록 하겠다!

Moya의 개념

Moya의 구성요소

1. Provider

모든 네트워크 서비스와 상호작용할 때 만들고 사용하는 객체
초기화 시 Moya Target을 가지게 된다.

2. Target

일반적으로 전체 API 서비스를 설명한다!

3. Endpoint

실제 URLRequest를 요청하게 된다.

  • Provider가 Target을 EndPoint로 전환한다.
  • EndPoint에는 Target에 해당하는 모든 데이터가 포함되어 있다!

모야로 하는 서버통신 순서대로

1. 요청, 응답 모델 구현하기(Dto)

서버에 요청할 값의 틀을 만든다고 생각하면 된다.
예를 들어 로그인이라면 이메일과 비밀번호가 필요할 것이다.
이걸 먼저 Dto로 정의를 해두는 것이다!!
https://app.quicktype.io -> 이걸로 Json코드를 바로 Swift로 바꿔서 사용하자!

1-1. 요청 모델 구현하기 (RequestDto)

서버에 요청할 모델을 작성한다. -> struct로 만들기

import Foundation

// MARK: - SignupRequestDto

struct SignupRequestDto: Codable {
    var email: String
    var name: String
    var password: String
}

// MARK: - LoginRequestDto

struct LoginRequestvaSDto: Codable {
    var email: String
    var password: String
}

1-2. 응답 모델 구현하기 (ResponseDto)

서버에서 응답받을 모델을 작성한다. -> struct로 만들기

import Foundation

// MARK: - LoginResponseDto
struct LoginResponseDto: Codable {
    let status: Int
    let message: String
    let result: Results?
}

/// Moya의 Result와 충돌이 나기 때문에 뒤에 s 하나만 붙여주세요!
// MARK: - Results
struct Results: Codable {
    let id: Int
    let name: String
    let profileImage, bio: String?
    let email, password: String
}

2. 열거형 Target 만들기

2-1. API 목록 정하기

Enum 을 사용해서 사용할 API 목록을 작성해줍니다.

  • 각 기능에 맞는 API를 enum을 통해서 선언해준다.
enum UserRouter {
    case signup(param: SignupRequestDto)
    case login(param: LoginRequestDto)
}

2-2. Target 정의하기

아래 나와있는 Target들을 정의할것이다!

  • Enum으로 선언한 API를 extension해서 TargetType들을 정의할것이다.
  • 각 프로퍼티마다 switch-case를 통해서 각각 기능에 맞게 정의해준다.

🚨Target Property

baseURL : Server base URL 지정
path : API Path 지정
method : HTTP Method 지정
sampleData : Mock Data for Test
task : Parameters for request 지정
validationType : 허용할 response 정의 - validationType 참고
headers : HTTP headers 적용

import Foundation
import UIKit

import Moya

enum UserRouter {
    case signup(param: SignupRequestDto)
    case login(param: LoginRequestDto)
}

extension UserRouter: TargetType {
    var baseURL: URL {
        return URL(string: Environment.baseURL)!
    }
    
    var path: String {
        switch self {
        case .signup(param: _):
            return "/user/signup"
        case .login(param: _):
            return "/user/signin"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .signup(param: _):
            return .post
        case .login(param: _):
            return .post
        }
    }
    
    var task: Task {
        switch self {
        case .signup(param: let param):
//            return .requestJSONEncodable(param)
            return .requestParameters(parameters: try! param.asParameter(), encoding: JSONEncoding.default)
            
        case .login(param: let param):
            return .requestParameters(parameters: try! param.asParameter(), encoding: JSONEncoding.default)
        }
    }
    
    var headers: [String : String]? {
        return ["Content-Type": "application/json"]
    }
}

3. Provider 객체 선언하기

서버통신을 하기 위해서 Provider 객체를 선언해준다!

  • MoyaProvider<""Target""> 이런식으로 선언해주면 된다!
let userProvider = MoyaProvider<UserRouter>()

4. 네트워크 요청 / 처리

서버에 요청했을 때의 결과값을 받아오는 부분이다.
음 버튼을 눌렀을때! 서버통신을 한다!
라고 가정을 하면 버튼을 누르는 행위에 통신함수를 적어두면 좋겠죠?
이건 코드로만 설명 -> 매번 달라질거 같기 때문 So 느낌만!

// MARK: - Action Helpers
    
    @objc
    private func touchupSubmitButton() {
        if let email = emailView.popInput(),
           let name = nameView.popInput(),
           let password = passwordView.popInput() {
            let param = SignupRequestDto(email: email, name: name, password: password)
            signup(param: param)
        }
    }
    
    // MARK: - Network Helpers
    
    private func signup(param: SignupRequestDto) {
        userProvider.request(.signup(param: param)) { response in
            switch response {
            case .success(let result):
                let status = result.statusCode
                if status >= 200 && status < 300 {
                    self.pushToLogin()
                }
                else if status >= 400 {
                    
                }
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
}
profile
안뇽희디

0개의 댓글