Trying to map an AlamoFire JSON response to a Class and receiving "Fatal Error: Unexpectedly found nil while unwrapping optional"
Trying to map an AlamoFire JSON response to a Class and receiving "Fatal Error: Unexpectedly found nil while unwrapping optional"
我正在使用 AlamoFire 拉动我的 API 来填充我的 tableView 的单元格。该应用程序能够构建,但在使用惯用 "Fatal Error: unexpectedly found nil while unwrapping an Optional value." 后不久就崩溃了我已经检查了所有可选值,但无法找出导致问题的原因。 Xcode 说问题出现在 AlamoFire 的 .map 部分。任何帮助将不胜感激。
在我开始编写代码之前,我的 JSON 中的一个值对于每个键都是空的(我没有写 JSON)。它不是 "null",只是空值。即使我没有将该键映射到我的 Class,这是否会导致问题?
JSON 是字典数组。发出 .GET 请求后,我获取 JSON 响应并将其映射到我初始化为 Class 类型数组的变量。
代码如下:
var users = [User]() //User is the class I created
var results = NSMutableOrderedSet()
let url = "http://www.example.com"
let appToken = "abcd12345"
Alamofire.request(.GET, url, parameters: ["appToken": appToken]).responseJSON() {
(_, _, JSON, _) in
let users = (JSON!.valueForKey("results") as! [NSDictionary]).map {
User(name: [=10=]["username"] as! String, image: [=10=]["profileImage"] as! String, email: [=10=]["email"] as! String, lat: [=10=][("lat" as NSString).doubleValue] as! Double, lon: [=10=][("lon" as NSString).doubleValue] as! Double, distance: [=10=]["status"] as! Int)
}
self.results.addObjectsFromArray(users)
self.localTableView!.reloadData()
}
这是我的 User.swift 中的 Class 类型:
class User: NSObject, MKAnnotation {
var name:String!
var profileImage:String!
var email:String!
var lat:Double
var lon:Double
var distance:Int!
var coordinate: CLLocationCoordinate2D
var title: String
var subtitle: String
var imageName: String
var userID:String!
var firstName: String!
var lastName: String!
init(name:String, image:String, email:String, lat:Double, lon:Double, distance:Int){
self.name = name
self.profileImage = image
self.email = email
self.lat = lat
self.lon = lon
self.distance = distance
self.coordinate = CLLocationCoordinate2DMake(lat, lon)
self.title = name
self.subtitle = twitterName
self.imageName = "image.png"
}
我在一些帮助部分读到我可能没有正确初始化 class 的实例,但我尝试了所有组合都无济于事。我也尝试过使用 NSMutableDictionary,但没有解决任何问题。
您的回调中有大量可选的解包,其中任何一个都可能为零。您需要进入调试器并检查返回的 JSON。如果您在使用调试器时遇到困难,您可以在尝试使用 JSON 变量并查看内容之前打印 () 变量。
提示:不要在 class 属性上使用隐式展开的可选类型。这不是一个安全的做法。如果您不打算在创建 class 实例后修改 属性,请使用 let name: String 代替 var name: String!。让编译器帮你写出正确的程序。
谢谢大家的回复。他们都非常有帮助。
我在上面分享时将部分代码缩短为要点,但在将 var lat
和 var lon
映射到我的用户数组时发现了问题。在 API 中,它们是双打,但被放在引号中,所以它把它读作一个字符串。我已经意识到这个问题并编写代码将它们从字符串转换为双打。但是,我将其放在代码的 .map{}
部分(上面未显示)。那里可能有办法做到这一点,但它对我没有用。
相反,我通过更改 class User
来找到解决方案,如下所示:
let lat: String
let lon: String
var latDouble: Double
var lonDouble: Double
然后初始化如下:
self.latDouble = (lat as NSString).doubleValue
self.lonDouble = (lon as NSString).doubleValue
我还合并了 SwiftyJSON 来检索我的 API 数据,然后按如下方式填充我的数组:
Alamofire.request(.GET, url, parameters: ["appToken": appToken]).responseJSON(){
(_,_,json,_) in
if (json != nil){
var jsonObj = JSON(json!)
if let userArray = jsonObj ["results"].array {
for userDict in userArray {
var name: String! = userDict["username"].string
var email: String! = userDict["email"].string
var image: String! = userDict["profileImage"].string
var lat: String! = userDict["lat"].string
var lon: String! = userDict["lon"].string
var distance: Int! = userDict["status"].int
var user = User(name: name, image: image, email: email, lat: lat, lon: lon, distance: distance)
self.users.append(user)
}
self.localTableView.reloadData()
}
我意识到这可能不是最好或唯一的解决方案,但它解决了我的问题。我希望这可能对其他人有帮助。再次感谢。
我正在使用 AlamoFire 拉动我的 API 来填充我的 tableView 的单元格。该应用程序能够构建,但在使用惯用 "Fatal Error: unexpectedly found nil while unwrapping an Optional value." 后不久就崩溃了我已经检查了所有可选值,但无法找出导致问题的原因。 Xcode 说问题出现在 AlamoFire 的 .map 部分。任何帮助将不胜感激。
在我开始编写代码之前,我的 JSON 中的一个值对于每个键都是空的(我没有写 JSON)。它不是 "null",只是空值。即使我没有将该键映射到我的 Class,这是否会导致问题?
JSON 是字典数组。发出 .GET 请求后,我获取 JSON 响应并将其映射到我初始化为 Class 类型数组的变量。
代码如下:
var users = [User]() //User is the class I created
var results = NSMutableOrderedSet()
let url = "http://www.example.com"
let appToken = "abcd12345"
Alamofire.request(.GET, url, parameters: ["appToken": appToken]).responseJSON() {
(_, _, JSON, _) in
let users = (JSON!.valueForKey("results") as! [NSDictionary]).map {
User(name: [=10=]["username"] as! String, image: [=10=]["profileImage"] as! String, email: [=10=]["email"] as! String, lat: [=10=][("lat" as NSString).doubleValue] as! Double, lon: [=10=][("lon" as NSString).doubleValue] as! Double, distance: [=10=]["status"] as! Int)
}
self.results.addObjectsFromArray(users)
self.localTableView!.reloadData()
}
这是我的 User.swift 中的 Class 类型:
class User: NSObject, MKAnnotation {
var name:String!
var profileImage:String!
var email:String!
var lat:Double
var lon:Double
var distance:Int!
var coordinate: CLLocationCoordinate2D
var title: String
var subtitle: String
var imageName: String
var userID:String!
var firstName: String!
var lastName: String!
init(name:String, image:String, email:String, lat:Double, lon:Double, distance:Int){
self.name = name
self.profileImage = image
self.email = email
self.lat = lat
self.lon = lon
self.distance = distance
self.coordinate = CLLocationCoordinate2DMake(lat, lon)
self.title = name
self.subtitle = twitterName
self.imageName = "image.png"
}
我在一些帮助部分读到我可能没有正确初始化 class 的实例,但我尝试了所有组合都无济于事。我也尝试过使用 NSMutableDictionary,但没有解决任何问题。
您的回调中有大量可选的解包,其中任何一个都可能为零。您需要进入调试器并检查返回的 JSON。如果您在使用调试器时遇到困难,您可以在尝试使用 JSON 变量并查看内容之前打印 () 变量。
提示:不要在 class 属性上使用隐式展开的可选类型。这不是一个安全的做法。如果您不打算在创建 class 实例后修改 属性,请使用 let name: String 代替 var name: String!。让编译器帮你写出正确的程序。
谢谢大家的回复。他们都非常有帮助。
我在上面分享时将部分代码缩短为要点,但在将 var lat
和 var lon
映射到我的用户数组时发现了问题。在 API 中,它们是双打,但被放在引号中,所以它把它读作一个字符串。我已经意识到这个问题并编写代码将它们从字符串转换为双打。但是,我将其放在代码的 .map{}
部分(上面未显示)。那里可能有办法做到这一点,但它对我没有用。
相反,我通过更改 class User
来找到解决方案,如下所示:
let lat: String
let lon: String
var latDouble: Double
var lonDouble: Double
然后初始化如下:
self.latDouble = (lat as NSString).doubleValue
self.lonDouble = (lon as NSString).doubleValue
我还合并了 SwiftyJSON 来检索我的 API 数据,然后按如下方式填充我的数组:
Alamofire.request(.GET, url, parameters: ["appToken": appToken]).responseJSON(){
(_,_,json,_) in
if (json != nil){
var jsonObj = JSON(json!)
if let userArray = jsonObj ["results"].array {
for userDict in userArray {
var name: String! = userDict["username"].string
var email: String! = userDict["email"].string
var image: String! = userDict["profileImage"].string
var lat: String! = userDict["lat"].string
var lon: String! = userDict["lon"].string
var distance: Int! = userDict["status"].int
var user = User(name: name, image: image, email: email, lat: lat, lon: lon, distance: distance)
self.users.append(user)
}
self.localTableView.reloadData()
}
我意识到这可能不是最好或唯一的解决方案,但它解决了我的问题。我希望这可能对其他人有帮助。再次感谢。