如何根据响应状态代码处理来自同一端点的不同json对象并映射到不同模型?

时间:2019-07-19 17:06:46

标签: json swift urlsession

向我的API服务上的特定终结点发出请求时,响应JSON结构会根据成功/失败的身份验证而更改。我有一个简单的类,它向服务器发出POST请求并解析JSON并将其映射到Model,但是,如果响应如果“不成功”(401状态码),它将无法映射,尽管我没有期望它映射到“成功”模型,我想知道如果状态码不同,如何使它映射到“不成功模型”?

型号


// MARK: - LoginResponse (SUCCESSFUL -- status code : 200)
class LoginResponse: Codable {
    let message, oauthToken, status: String
    let userData: [UserDatum]

    enum CodingKeys: String, CodingKey {
        case message
        case oauthToken = "oauth_token"
        case status
        case userData = "user_data"
    }

    init(message: String, oauthToken: String, status: String, userData: [UserDatum]) {
        self.message = message
        self.oauthToken = oauthToken
        self.status = status
        self.userData = userData
    }
}

// MARK: - UserDatum
class UserDatum: Codable {
    let emailAddress, firstName, lastName, phoneNumber: String
    let userID: String
    let userOnboardStage: Int

    enum CodingKeys: String, CodingKey {
        case emailAddress = "email_address"
        case firstName = "first_name"
        case lastName = "last_name"
        case phoneNumber = "phone_number"
        case userID = "user_id"
        case userOnboardStage = "user_onboard_stage"
    }

    init(emailAddress: String, firstName: String, lastName: String, phoneNumber: String, userID: String, userOnboardStage: Int) {
        self.emailAddress = emailAddress
        self.firstName = firstName
        self.lastName = lastName
        self.phoneNumber = phoneNumber
        self.userID = userID
        self.userOnboardStage = userOnboardStage
    }
}


// MARK: - FailedLoginResponse (UNSUCCESSFUL -- status code : 401)
class FailedLoginResponse: Codable {
    let errorMessage, status: String

    enum CodingKeys: String, CodingKey {
        case errorMessage = "error_message"
        case status
    }

    init(errorMessage: String, status: String) {
        self.errorMessage = errorMessage
        self.status = status
    }
}


网络服务等级


enum APIError:Error{

    case responseProblem
    case decodingProblem
    case encodingProblem
}


struct APIRequest {

    let resourceURL: URL
    let parameters: Dictionary<String, String>

    init(endpoint: String, email: String, password: String){

        let resourceString = "https://url/api/v1/auth/\(endpoint)"
        guard let resourceURL = URL(string: resourceString) else {fatalError()}

        self.resourceURL = resourceURL

        var parameters = Dictionary<String, String>()

        parameters = ["email_address":email,
                      "password":password,
                      "user_device_token":"",
                      "client_id":"",
                      "client_secret":""]

        self.parameters = parameters

    }




    func save(_ loginResponseToSave:LoginResponse, completion: @escaping(Result<LoginResponse, APIError>) -> Void){





        do {

            var urlRequest = URLRequest(url : resourceURL)

            urlRequest.httpMethod = "POST"
            urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
            urlRequest.httpBody = try JSONEncoder().encode(self.parameters)

            let dataTask = URLSession.shared.dataTask(with: urlRequest){ data , response, _ in

                guard let httpResponse  = response as? HTTPURLResponse, httpResponse.statusCode == 200, let jsonData = data else {


                    completion(.failure(.responseProblem))
                    return
                }


       /// WHAT I WANT TO DO ////

        if httpResponse == 401{

          // map to unsuccessful model

         }

      ////////





                do {

                    //map response to model
                    let loginData = try JSONDecoder().decode(LoginResponse.self, from: jsonData)

                    completion(.success(loginData))


                }catch{

                    completion(.failure(.decodingProblem))
                }
            }
            dataTask.resume()

        }catch{

            completion(.failure(.encodingProblem))

        }


    }


}




我希望能够根据响应状态代码将响应映射到其他模型,因此我可以将此反馈推送到视图以供用户通知。例如。向用户显示-“您输入了错误的凭据”

0 个答案:

没有答案