음 개념은 나중에 좀 더 구체적으로 정리하고
여기서는 내가 서버통신을 할 때 어떤 순서로 차분하고 정확하게 서버통신을 해야되는지
그거에 중점을 둬서 정리하도록 하겠다!
모든 네트워크 서비스와 상호작용할 때 만들고 사용하는 객체
초기화 시 Moya Target을 가지게 된다.
일반적으로 전체 API 서비스를 설명한다!
실제 URLRequest를 요청하게 된다.
- Provider가 Target을 EndPoint로 전환한다.
- EndPoint에는 Target에 해당하는 모든 데이터가 포함되어 있다!
서버에 요청할 값의 틀을 만든다고 생각하면 된다.
예를 들어 로그인이라면 이메일과 비밀번호가 필요할 것이다.
이걸 먼저 Dto로 정의를 해두는 것이다!!
https://app.quicktype.io -> 이걸로 Json코드를 바로 Swift로 바꿔서 사용하자!
서버에 요청할 모델을 작성한다. -> 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
}
서버에서 응답받을 모델을 작성한다. -> 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
}
Enum 을 사용해서 사용할 API 목록을 작성해줍니다.
- 각 기능에 맞는 API를 enum을 통해서 선언해준다.
enum UserRouter {
case signup(param: SignupRequestDto)
case login(param: LoginRequestDto)
}
아래 나와있는 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"]
}
}
서버통신을 하기 위해서 Provider 객체를 선언해준다!
- MoyaProvider<""Target""> 이런식으로 선언해주면 된다!
let userProvider = MoyaProvider<UserRouter>()
서버에 요청했을 때의 결과값을 받아오는 부분이다.
음 버튼을 눌렀을때! 서버통신을 한다!
라고 가정을 하면 버튼을 누르는 행위에 통신함수를 적어두면 좋겠죠?
이건 코드로만 설명 -> 매번 달라질거 같기 때문 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)
}
}
}
}