Разбор ответа JSON в ObjectMapper - PullRequest
0 голосов
/ 29 мая 2019

В настоящее время я делаю переход с Android на iOS, лучше сказал Java на Swift, я получил общий ответ в JSON, но я не могу использовать его как объект и показать его в раскадровке.Я действительно новичок в Swift, поэтому я застрял на некоторое время.

Я пробовал ObjectMapper, а также декодирование JSON без результата вообще.

Я объявил этот ответ, как яиспользуется в Java (Android)

class ResponseObjectMapper<T,R>: Mappable where T: Mappable,R:Mappable{

var data:T?
var message:String!
var error:R?

required init?(_ map: Map) {
    self.mapping(map: map)
}

func mapping(map: Map) {
    data          <- map["data"]
    message          <- map["message"]
    error          <- map["error"]
}
}

class UserMapper :Mappable{
var email:String?
var fullName:String?
var id:CLong?
var phoneNumber:String?
var token:CLong?

required init?(_ map: Map) {
}

func mapping(map: Map) {
    email <- map["email"]
    fullName <- map["fullName"]
    id <- map["id"]
    phoneNumber <- map["phoneNumber"]
    token <- map["token"]
    phoneNumber <- map["phoneNumber"]
}
}    

В моем проекте Android я использую зависимость Gson и смог использовать JSON в качестве объекта

class ErrorMapper:Mappable{

var message:String?
var code:Int?

required init?(_ map: Map) {
}

func mapping(map: Map) {
    message          <- map["message"]
    code          <- map["code"]
}

}

Это Alamofire , который дал мне JSON.

func login(params: [String:Any]){Alamofire.request
("http://192.168.0.192:8081/SpringBoot/user/login", method: .post, 
parameters: params,encoding: JSONEncoding.default, headers: 
headers).responseJSON {
            response in
            switch response.result {
            case .success:

                let response = Mapper<ResponseObjectMapper<UserMapper,ErrorMapper>>.map(JSONString: response.data)


                break
            case .failure(let error):

                print(error)
            }
        }
}

Если я распечатываю ответ с печатью (ответ), я получаю

SUCCESS: {
data =     {
    email = "vpozo@montran.com";
    fullName = "Victor Pozo";
    id = 6;
    phoneNumber = 099963212;
    token = 6;
};
error = "<null>";
message = SUCCESS;
}

, и если я использую этот код, я могу получить результат с ключом и значением, но я не получаюзнаю, как использовать его в качестве объекта

if let result = response.result.value {
                    let responseDict = result as! [String : Any]
                    print(responseDict["data"])
                }

консоль:

Optional({
email = "vpozo@gmail.com";
fullName = "Victor Pozo";
id = 6;
phoneNumber = 099963212;
token = 6;
})

Я хотел бы использовать его в объекте, например user.token в контроллере вида, вероятно, я 'Я действительно запутался, пытаясь сопоставить с общими атрибутами.

Type 'ResponseObjectMapper<UserMapper, ErrorMapper>' does not conform to protocol 'BaseMappable'

1 Ответ

0 голосов
/ 30 мая 2019

Прежде всего вам понадобится сетевой менеджер, который использует Alamofire для выполнения всех ваших запросов. Я сделал обобщенный, который выглядит примерно так. Вы можете изменить его, как хотите.

import Foundation
import Alamofire
import SwiftyJSON

class NetworkHandler: NSObject {

let publicURLHeaders : HTTPHeaders = [
    "Content-type" : "application/json"
]

let privateURLHeaders : HTTPHeaders = [
    "Content-type" : "application/json",
    "Authorization" : ""
]

enum RequestType {
    case publicURL
    case privateURL
}

func createNetworkRequestWithJSON(urlString : String , prametres : [String : Any], type : RequestType, completion:@escaping(JSON) -> Void) {

    let internetIsReachable = NetworkReachabilityManager()?.isReachable ?? false
    if !internetIsReachable {
        AlertViewManager.sharedInstance.showAlertFromWindow(title: "", message: "No internet connectivity.")
    } else {
        switch type {
        case .publicURL :
            commonRequest(urlString: baseURL+urlString, parameters: prametres, completion: completion, headers: publicURLHeaders)
            break
        case .privateURL:
            commonRequest(urlString: baseURL+urlString, parameters: prametres, completion: completion, headers: privateURLHeaders)
            break
        }
    }
}

func commonRequest(urlString : String, parameters : [String : Any], completion : @escaping (JSON) -> Void , headers : HTTPHeaders){

    print("urlString:"+urlString)
    print("headers:")
    print(headers)
    print("parameters:")
    print(parameters)

    let url = NSURL(string: urlString)
    var request = URLRequest(url: url! as URL)
    request.httpMethod = "POST"
    request.httpHeaders = headers
    request.timeoutInterval = 10
    let data = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)

    let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
    if let json = json {
        print("parameters:")
        print(json)
    }

    request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)
    let alamoRequest = AF.request(request as URLRequestConvertible)
    alamoRequest.validate(statusCode: 200..<300)
    alamoRequest.responseJSON{ response in
        print(response.response?.statusCode as Any )
        if let status = response.response?.statusCode {
            switch(status){
            case 201:
                print("example success")
                SwiftLoader.hide()
            case 200 :
                if let json = response.value {
                    let jsonObject = JSON(json)
                    completion(jsonObject)
                }
            default:
                SwiftLoader.hide()
                print("error with response status: \(status)")
            }
        }else{
            let jsonObject = JSON()
            completion(jsonObject)
            SwiftLoader.hide()
        }
    }
}
}

После этого, когда вам понадобится сделать запрос, вы можете использовать эту функцию. Это будет принимать параметры, если они необходимы, и после завершения запроса он выполнит функцию обратного вызова, в которой вы можете обработать ответ. Ответ здесь будет в формате SWIFTYJSON.

func makeNetworkRequest(){
    let networkHandler = NetworkHandler()
    var parameters : [String:String] = [:]
    parameters["email"] = usernameTextField.text
    parameters["pass"] = passwordTextField.text
    networkHandler.createNetworkRequestWithJSON(urlString: "http://192.168.0.192:8081/SpringBoot/user/login", prametres: parameters, type: .publicURL, completion: self.handleResponseForRequest)
}


func handleResponseForRequest(response: JSON){
    if let message = response["message"].string{
        if message == "SUCCESS"{

            if let email = response["data"]["email"].string{
                //Do something with email.
            }

            if let fullName = response["data"]["fullName"].string{
                //Do something with fullName.
            }

            if let id = response["data"]["id"].int{
                //Do something with id.
            }

            if let phoneNumber = response["data"]["phoneNumber"].int64{
                //Do something with phoneNumber.
            }

            if let token = response["data"]["token"].int{
                //Do something with token.
            }
        }else{
            //Error
        }
    }
}

Надеюсь, это поможет. Дайте мне знать, если вы застряли где-нибудь.

...