iyOmSd/Title: Swift

[Swift] - Alamofire 5.1 변경된 통신 및 Json Dynamic Key

냄수 2020. 5. 18. 22:53
반응형

2019/10/27 - [iyOmSd/Title: Swift] - [Swift] Alamofire를 사용하여 API JSON 데이터 받기 (1/2)

예전에 Alamofire을 사용해서 통신했었는데요!!

 

Swift버전도 올라가고, 더좋은 방향으로 발전해나가기 때문에 변경사항이 좀 있어요!!

사용법은 거의 비슷한데 살짝 바꼈더라구요

 

글작성시 사용한 Alamofire 버전은 5.1 이구요!

struct LoginServiceImp: LoginServiceProtocol {
    func requestSignUp(form: SignUpForm) {
        
        var urlComponent = URLComponents(string: BaseURL.shared.getBaseString())
        urlComponent?.path = RequestURL.signUp.getURLString
        
        guard let url = urlComponent?.url else {
            return
        }
        let header: HTTPHeaders = [
            "Content-Type": "application/json"
        ]
        let body: Parameters = [
            "id": form.id,
            "password": form.pw,
            "name": form.name,
            "email": form.email,
            "phone": form.phone
        ]
        
        let request = AF.request(url, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header)
        request
            .validate(statusCode: 200..<500)
            .responseDecodable(of: SimpleResponse<String>.self) { response in
                switch response.result {
                case .success:
                    print(response.value)
                    print(response.value?.message)
                case .failure(let err):
                    print(err)
                }
        }
    }
}

앞서서 게시글에서 설명했기때문에 바뀐 점만 빠르게 짚어볼게요

 

Alamofire.request 접근이아닌

AF.request접근..!

 

 

validate(statusCode: )

유효한 statusCode를 분류해줘요

이 코드속에 속해야만 실행되요

 

여기서말하는 statusCode는 헤더로 날라오는 코드에요

json안의 코드와 헷갈리시면 안되요

validate(contentType: )

다른속성으로 contentType도 있어요

원하는 contentType만 받을수 있을거같죠?

 

responseDecodable(of: )

원하는 모델로 바로 디코딩을 해서 반환해줘요

let decoder = JSONDecoder()
let json = try decoder.decode(LoginResult.self, from: result)

이전의 방식은 위처럼 통신이 성공하면 디코딩을 해주고 모델에 맞게 해줬었는데

아래와같이 이작업을 한번에 해서 모델이 반환되요

 

.responseDecodable(of: LoginResult.self) { response in
    ...
}

 

response.result 는 Result타입이 반환되구요

response.value 는 디코딩된 모델이 반환되요

 

response.value를 통해서 후처리를 해주면 되요

 

 

 

모델을 만들때 json으로 받는 key값들이

 

statusCode

message

data

이렇게 3개의 키값을 받는것도 있고

 

statusCode

message

2개만 받는 것도있다고 가정할 때

data가 있을때도 없을때도 있잖아요?

 

그럼 모델을 2개를 만들어서 사용하나요..??

그렇게 사용해도 가능은해요

하지만 살짝 번거롭죠

 

그래서 아래와같이

decoder를 재정의해주면되요

CodingKeys를 다시정의해주고

decode를 해주고 없으면 nil을 넣어줌으로써

data키값이 있을때, 없을때 모두 공통으로 사용할 수 있는 모델을 만들 수 있어요 

struct SimpleResponse<T: Codable>: Codable {
    let statusCode: Int?
    let message: String?
    let data: T?
    
    enum CodingKeys: CodingKey {
        case statusCode, message, data
    }
    
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        statusCode = (try? values.decode(Int.self, forKey: .statusCode)) ?? nil
        message = (try? values.decode(String.self, forKey: .message)) ?? nil
        data = (try? values.decode(T.self, forKey: .data)) ?? nil
    }
}
반응형