将 responseJSON 解析为 ObjectMapper
Posted
技术标签:
【中文标题】将 responseJSON 解析为 ObjectMapper【英文标题】:Parse responseJSON to ObjectMapper 【发布时间】:2019-05-29 19:55:20 【问题描述】:我目前正在从 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"]
这是给我 JSON 的 Alamofire。
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)
如果我用 print(response) 打印响应,我得到了
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;
)
我想在 Object 中使用它,例如在 View Controller 中使用 user.token
,可能我真的很困惑,尝试使用通用属性进行映射。
Type 'ResponseObjectMapper<UserMapper, ErrorMapper>' does not conform to protocol 'BaseMappable'
【问题讨论】:
嗨 Victor... 请查看 SwiftyJSON 库以了解 swift。它可以帮助您直接将 JSON 响应作为对象获取。这是链接 => github.com/SwiftyJSON/SwiftyJSON 嗨@CedanMisquith,我一直在尝试一些在cocoapods 中的依赖项,安装了Swifty,但我不知道如何使用数据键和值,然后将其解析为对象。我会再试一次谢谢。 我绝对可以帮助您编写代码。这很简单,我将以您的 JSON 为例并发布答案。 【参考方案1】:首先,您需要一个使用 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
希望这会有所帮助。如果您遇到任何问题,请告诉我。
【讨论】:
感谢您的帮助@CedanMisquith,但我对经理有疑问,我收到了这个错误。 “URLRequest”类型的值在请求中没有成员“httpHeaders”。httpHeaders = headers 现在可以使用了吗? .allHTTPHEaderFields 还有一个问题,所以我在我的视图控制器上使用了一个点击按钮,然后它调用了一个像 makeNetworkRequest 这样的函数,我应该如何调用一个新的控制器并使用该数据,在 Android 中我使用一个包,但是我可以如何使用swift中新视图中的数据,非常感谢您的帮助 所以我认为标题错误正在发生,因为您获得了最新版本的 Alamofire 库并且语法已更改。所以我认为改变语法是你做的正确的事情。现在告诉我我是否正确......您想在服务器请求成功响应后移动到新的视图控制器,然后您想在新的视图控制器中使用该响应吗??? 好吧,你现在卡在哪里了吗??您是否能够访问新视图控制器中的数据?? SwiftyJSON 完成了一切,我能够使用带有构造函数init(userView:JSON) self.fullName = userView["fullName"].stringValue
的结构将其解析为对象,然后使用 completion:@escaping(JSON) -> Void
将其解析为对象,然后在 viewController let user=UserObject(userObject:userJson)
中解析它。您的问题的答案是肯定的,我想显示用户信息以及如何保留令牌以在其他请求中使用它。我还需要迭代帐户才能在pickerview 上使用它let jsonAccounts = response["data"]
给了我2 个帐户。顺便说一句非常感谢您的帮助
所以要存储Token
,您可以查看UserDefaults
。这将帮助您以 key
名称将令牌存储在您的应用中,您可以使用该 key
在您的应用中的任何位置检索它。以上是关于将 responseJSON 解析为 ObjectMapper的主要内容,如果未能解决你的问题,请参考以下文章
Gradle 3.4.1 无法使用 Proguard 将响应解析为 Object
SwiftyJSON Alamofire 无法使用类型为 ((_,_,_,_))->_) 的参数列表调用 responseJSON