有没有办法正确反序列化对Swift对象的JSON响应resp.使用DTO作为固定JSON API的容器?
类似于http://james.newtonking.com/json的东西或类似Java的这个例子
User user = jsonResponse.readEntity(User.class);
Run Code Online (Sandbox Code Playgroud)
jsonResponse.toString()就像这样的东西
{
"name": "myUser",
"email": "user@example.com",
"password": "passwordHash"
}
Run Code Online (Sandbox Code Playgroud)
moh*_*acs 60
因为您为一个非常简单的JSON对象提供了为处理该模型而准备的代码.如果您需要更复杂的JSON模型,则需要改进此示例.
您的自定义对象
class Person : NSObject {
var name : String = ""
var email : String = ""
var password : String = ""
init(JSONString: String) {
super.init()
var error : NSError?
let JSONData = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let JSONDictionary: Dictionary = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &error) as NSDictionary
// Loop
for (key, value) in JSONDictionary {
let keyName = key as String
let keyValue: String = value as String
// If property exists
if (self.respondsToSelector(NSSelectorFromString(keyName))) {
self.setValue(keyValue, forKey: keyName)
}
}
// Or you can do it with using
// self.setValuesForKeysWithDictionary(JSONDictionary)
// instead of loop method above
}
}
Run Code Online (Sandbox Code Playgroud)
这就是您使用JSON字符串调用自定义类的方法.
override func viewDidLoad() {
super.viewDidLoad()
let jsonString = "{ \"name\":\"myUser\", \"email\":\"user@example.com\", \"password\":\"passwordHash\" }"
var aPerson : Person = Person(JSONString: jsonString)
println(aPerson.name) // Output is "myUser"
}
Run Code Online (Sandbox Code Playgroud)
Sye*_*sar 10
我建议您使用代码生成(http://www.json4swift.com)从json响应中创建本机模型,这将节省您手动解析的时间,并降低因错误键导致错误的风险,所有元素可以通过模型属性访问,这将是纯粹的原生,模型将更有意义,而不是检查键.
您的转换将非常简单:
let userObject = UserClass(userDictionary)
print(userObject!.name)
Run Code Online (Sandbox Code Playgroud)
斯威夫特2:我真的很喜欢上一篇莫哈奇的帖子!为了使它更面向对象,我写了一个匹配的扩展:
extension NSObject{
convenience init(jsonStr:String) {
self.init()
if let jsonData = jsonStr.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
{
do {
let json = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String: AnyObject]
// Loop
for (key, value) in json {
let keyName = key as String
let keyValue: String = value as! String
// If property exists
if (self.respondsToSelector(NSSelectorFromString(keyName))) {
self.setValue(keyValue, forKey: keyName)
}
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
else
{
print("json is of wrong format!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
自定义类:
class Person : NSObject {
var name : String?
var email : String?
var password : String?
}
class Address : NSObject {
var city : String?
var zip : String?
}
Run Code Online (Sandbox Code Playgroud)
使用JSON字符串调用自定义类:
var jsonString = "{ \"name\":\"myUser\", \"email\":\"user@example.com\", \"password\":\"passwordHash\" }"
let aPerson = Person(jsonStr: jsonString)
print(aPerson.name!) // Output is "myUser"
jsonString = "{ \"city\":\"Berlin\", \"zip\":\"12345\" }"
let aAddress = Address(jsonStr: jsonString)
print(aAddress.city!) // Output is "Berlin"
Run Code Online (Sandbox Code Playgroud)
我写的另一个JSON处理程序:
有了它,你可以这样:
let obj:[String:AnyObject] = [
"array": [JSON.null, false, 0, "", [], [:]],
"object":[
"null": JSON.null,
"bool": true,
"int": 42,
"double": 3.141592653589793,
"string": "a ?\t?\n",
"array": [],
"object": [:]
],
"url":"http://blog.livedoor.com/dankogai/"
]
let json = JSON(obj)
json.toString()
json["object"]["null"].asNull // NSNull()
json["object"]["bool"].asBool // true
json["object"]["int"].asInt // 42
json["object"]["double"].asDouble // 3.141592653589793
json["object"]["string"].asString // "a ?\t?\n"
json["array"][0].asNull // NSNull()
json["array"][1].asBool // false
json["array"][2].asInt // 0
json["array"][3].asString // ""
Run Code Online (Sandbox Code Playgroud)
如您所见!?,下标之间不需要.
除此之外,您可以像这样应用自己的架构:
//// schema by subclassing
class MyJSON : JSON {
override init(_ obj:AnyObject){ super.init(obj) }
override init(_ json:JSON) { super.init(json) }
var null :NSNull? { return self["null"].asNull }
var bool :Bool? { return self["bool"].asBool }
var int :Int? { return self["int"].asInt }
var double:Double? { return self["double"].asDouble }
var string:String? { return self["string"].asString }
var url: String? { return self["url"].asString }
var array :MyJSON { return MyJSON(self["array"]) }
var object:MyJSON { return MyJSON(self["object"]) }
}
let myjson = MyJSON(obj)
myjson.object.null // NSNull?
myjson.object.bool // Bool?
myjson.object.int // Int?
myjson.object.double // Double?
myjson.object.string // String?
myjson.url // String?
Run Code Online (Sandbox Code Playgroud)
Apple有一个很好的例子,使用 Swift 2.0 反序列化 JSON
诀窍是使用 Guard 关键字并链接分配,如下所示:
init?(attributes: [String : AnyObject]) {
guard let name = attributes["name"] as? String,
let coordinates = attributes["coordinates"] as? [String: Double],
let latitude = coordinates["lat"],
let longitude = coordinates["lng"],
else {
return nil
}
self.name = name
self.coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
Run Code Online (Sandbox Code Playgroud)
与任何第三方相比,我个人更喜欢本机解析,因为它是透明且无魔法的。(并且 bug 更少?)
| 归档时间: |
|
| 查看次数: |
61350 次 |
| 最近记录: |