Ios 在Swift中处理JSON解析时出错
我正在使用Ios 在Swift中处理JSON解析时出错,ios,json,swift,swift2,alamofire,Ios,Json,Swift,Swift2,Alamofire,我正在使用Alamofire并将返回的JSON解析为一个对象,如下所示: final class User: NSObject, ResponseObjectSerializable { var id: Int var facebookUID: String? var email: String var firstName: String var lastName: String var phone: String? var positio
Alamofire
并将返回的JSON解析为一个对象,如下所示:
final class User: NSObject, ResponseObjectSerializable {
var id: Int
var facebookUID: String?
var email: String
var firstName: String
var lastName: String
var phone: String?
var position: String?
var timeCreated: CVDate
init?(response: NSHTTPURLResponse, var representation: AnyObject) {
if let dataRepresentation = ((representation as! NSDictionary).valueForKey("data") as? [String: AnyObject]) {
representation = dataRepresentation
}
if let id = representation.valueForKeyPath("id") as? Int {
self.id = id
} else {
self.id = 0
}
if let facebookUID = representation.valueForKeyPath("facebook_UID") as? String {
self.facebookUID = facebookUID
}
if let email = representation.valueForKeyPath("email") as? String {
self.email = email
} else {
self.email = ""
}
if let firstName = representation.valueForKeyPath("first_name") as? String {
self.firstName = firstName
} else {
self.firstName = ""
}
if let lastName = representation.valueForKeyPath("last_name") as? String {
self.lastName = lastName
} else {
self.lastName = ""
}
if let phone = representation.valueForKeyPath("phone") as? String {
self.phone = phone
}
if let position = representation.valueForKeyPath("position_name") as? String {
self.position = position
}
if let timeCreated = representation.valueForKeyPath("time_created") as? String {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let date = formatter.dateFromString(timeCreated) {
self.timeCreated = CVDate(date: date)
} else {
self.timeCreated = CVDate(date: NSDate())
}
} else {
self.timeCreated = CVDate(date: NSDate())
}
}
}
我的问题是,这种风格是解码JSON和设置非可选实例变量的最佳方式吗?例如,在本声明中:
if let id = representation.valueForKeyPath("id") as? Int {
self.id = id
}
编译器要求我添加一个else子句,并将id
设置为某个值,否则xCode会抛出一个错误,说明:self.id未在隐式生成的super.init调用中初始化
但同时,用0
值初始化self.id
是错误的,对我没有任何帮助。你可以使用??要提供如下默认值:
self.id = (representation.valueForKeyPath("id") as? Int) ?? 0
let id: Int!
init? (inputJson: NSDictionary) {
if let id = inputJson["id"] as? Int {
self.id = id
} else {
// if we are initing from JSON, there MUST be an id
id = nil
cry(inputJson) // this logs the error
return nil
}
}
但同时,使用值0初始化self.id是错误的,对我没有任何帮助
如果为self.id
设置默认值感觉不正确,则应将此属性设置为可选属性。这样您就不必添加else子句:
final class User: NSObject, ResponseObjectSerializable {
var id: Int?
var facebookUID: String?
var email: String
var firstName: String
var lastName: String
var phone: String?
var position: String?
var timeCreated: CVDate
init?(response: NSHTTPURLResponse, var representation: AnyObject) {
if let dataRepresentation = ((representation as! NSDictionary).valueForKey("data") as? [String: AnyObject]) {
representation = dataRepresentation
}
if let id = representation.valueForKeyPath("id") as? Int {
self.id = id
}
...
更新
你在评论中说:
但我始终需要用户对象的id
如果你必须拥有这个id
属性,那么这个问题是没有意义的,你只需要这样做
let id = representation.valueForKeyPath("id") as! Int
并在前面保证该值将存在
因为如果你的对象需要一个ID,那么如果这个值不存在并且你不想要一个默认值,你就不能初始化它。虽然ResponseObjectSerializable
代码是Alamofire项目的一个很好的例子,但是使用一个具有实际错误状态的专用JSON解析库确实是一个更好的主意。这比使用optionals表示错误状态要好得多,或者必须为每个字段提供默认值,以防响应格式不正确
虽然它有一点学习曲线,但我更喜欢使用它进行JSON解析。一旦掌握了窍门,JSON解析就几乎是防弹的了。更好的是,它很容易与Alamofire集成,特别是今天发布的版本3。为了解决您对没有ID是错误条件的担忧,您可以使用一个可失败的初始值设定项。我在最近的一个项目中做到了这一点。看起来像这样:
self.id = (representation.valueForKeyPath("id") as? Int) ?? 0
let id: Int!
init? (inputJson: NSDictionary) {
if let id = inputJson["id"] as? Int {
self.id = id
} else {
// if we are initing from JSON, there MUST be an id
id = nil
cry(inputJson) // this logs the error
return nil
}
}
当然,这意味着您的代码将需要接受整个对象的初始化可能会失败。不过,我始终需要用户对象的id。如果我没有通过用户类提供错误,有没有一种方法可以抛出一个错误,或者在用户类中这样做是一种不好的做法?如果你必须有这个id
,那么所有这些都是没有意义的,你只需要做let id=representation.valueForKeyPath(“id”)as!Int
并在前面保证此值将存在。因为如果你的对象需要一个ID,那么如果这个值不存在,如果你不想要一个默认值,你无论如何也不能初始化。是的,我想这就是我要做的。我只是不希望应用程序崩溃,以防后端出现故障,并且由于任何原因没有向我提供id