如何将 Alamofire 中的数据映射到 Codable 对象的特定字段?

问题描述 投票:0回答:3

对于我的 APIManager.swift

        APIManager.manager.request(urlEncoded, method: useMethod, parameters: params, encoding: requestEncoding, headers: headers)
            .validate(statusCode: 200..<300)
            .responseJSON { response in
            switch response.result {
            case .success(let json):
                ///
            case .failure(let error):
                ///
            }
        }

还有我的 api json 响应

{
    "code": 200,
    "status": "success",
    "response_data": {
        "name": "testing"
    }
}

我的模型

struct TesterModel: Codable {
    var name: String
}

我需要使用可编码协议映射对象,但仅映射到 api 响应中的

reponse_data
字段。如何从 .responseJSON 映射它?

json swift api alamofire decodable
3个回答
1
投票

您可以对特定字段使用“CodingKeys”

enum CodingKeys

像这样:

struct Landmark: Codable {
    var name: String
    var foundingYear: Int
    var location: Coordinate
    var vantagePoints: [Coordinate]
    
    enum CodingKeys: String, CodingKey {
        case name = "title"
        case foundingYear = "founding_date"
        
        case location
        case vantagePoints
    }
}

也可以使用 JSONDecoder() 进行解码

guard let response = try? JSONDecoder().decode(Landmark, data) else { return nil }

在此处查看更多内容Apple 文档


0
投票

您可以像这样创建另一个模型:

struct APIResponse: Codable {
    var code: Int
    var status: String
    var responseData: TesterModel
}

struct TesterModel: Codable {
    var name: String
}

然后你就可以这样做:

APIManager.manager.request(urlEncoded, method: useMethod, parameters: params, encoding: requestEncoding, headers: headers)
            .validate(statusCode: 200..<300)
            .responseJSON { response in
            switch response.result {
                guard let data = response.data else {
                    return
                }
                do {
                    let result = try JSONDecoder().decode(APIResponse.self, from: data)
                }
                catch {
                    
                }
        }

0
投票
typealias JsonDictionay = [String : Any]

enum ServiceResponse {
    case success(response: JsonDictionay)
    case failure
    case notConnectedToInternet
}

enum ResponseStatusCode: Int {
    case success = 200
}

class BaseService {
    
    var dataRequestArray: [DataRequest] = []
    var sessionManager: [String : Alamofire.Session] = [:]
    
    func callEndPoint(endPoint: String, method: Alamofire.HTTPMethod = .get, headers: HTTPHeaders?, params: JsonDictionay? = [:], completion: @escaping (ServiceResponse) -> Void){
        
        let url = ""
        let dataRequest: DataRequest?
        
        switch method {
        case .post:
            dataRequest = AF.request(url, method: method, parameters: params, encoding: JSONEncoding.default, headers: headers).responseString { (response) in
                self.serializeResponse(response: response, completion: completion)
                self.sessionManager.removeValue(forKey: url)
            }
        default:
            dataRequest = AF.request(url, method: method, parameters: params, headers: headers).responseString { (response) in
                self.serializeResponse(response: response, completion: completion)
                self.sessionManager.removeValue(forKey: url)
            }
        }
    }
    
    func serializeResponse(response: AFDataResponse<String>, completion: @escaping (ServiceResponse) -> Void) {
        
        DispatchQueue.global(qos: .background).async { [weak self] in
            
            guard let strongSelf = self else { return }
            
            var json: Any?
            guard let urlResponse = response.response else {
                if let error = response.error as NSError?, error.code == NSURLErrorNotConnectedToInternet {
                    strongSelf.notConnectedToInternet(completion: completion)
                } else {
                    strongSelf.failure(completion: completion)
                }
                return
            }
            
            if let data = response.value?.data(using: String.Encoding.utf8) {
                do {
                    json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:AnyObject]
                } catch {
                    strongSelf.failure(completion: completion)
                    return
                }
            }
            
            guard let jsonResponse = json as? JsonDictionay else {
                strongSelf.failure(completion: completion)
                return
            }
            
            if jsonResponse["success"] as? Bool == false {
                strongSelf.failure(completion: completion)
                return
            }
            
            strongSelf.success(result:jsonResponse , headers: urlResponse.allHeaderFields, completion: completion)
        }
    }
    
    func cancelAllRequests () {
        for dataRequest in self.dataRequestArray {
            dataRequest.cancel()
        }
        self.dataRequestArray.removeAll()
    }
    
    func notConnectedToInternet (completion:@escaping (ServiceResponse) -> Void) {
        completion(.notConnectedToInternet)
    }
    
    func failure (completion:@escaping (ServiceResponse) -> Void) {
        completion(.failure)
    }
    
    func success (result: JsonDictionay?, headers: [AnyHashable: Any], completion:@escaping (ServiceResponse) -> Void) {
        completion(.success(response: result!))
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.