尝试将 AlamoFire JSON 响应映射到类并接收"Fatal Error: Unexpectedly found nil while unwrapping optional"



我正在使用AlamoFire提取API来填充表视图的单元格。该应用程序可以构建,但很快就崩溃了,通常会出现"致命错误:在打开可选值时意外发现nil"。我已经查看了所有可选值,但不知道是哪一个导致了问题。Xcode表示,问题出现在AlamoFire的.map部分。如有任何帮助,我们将不胜感激。

在我开始编写代码之前,JSON中的一个值对于每个键都是null(我没有编写JSON(。它不是"null",只是null。即使我没有将该键映射到我的类,这是否会导致问题?

JSON是一个字典数组。在发出.GET请求后,我将获取JSON响应并将其映射到一个变量,该变量已初始化为类类型数组。

这是代码:

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: $0["username"] as! String, image: $0["profileImage"] as! String, email: $0["email"] as! String, lat: $0[("lat" as NSString).doubleValue] as! Double, lon: $0[("lon" as NSString).doubleValue] as! Double, distance: $0["status"] as! Int)
        }
        self.results.addObjectsFromArray(users)
        self.localTableView!.reloadData()
    }

这是我的User.swift中的类类型:

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"

}

我在一些帮助部分中读到,我可能没有正确初始化类的实例,但我尝试了每种组合,但都没有成功。我也试过玩NSMutableDictionary,但没有解决任何问题。

感谢大家的回复。他们都很乐于助人。

当我在上面分享代码时,我将部分代码缩短为要点,但在将var latvar lon映射到我的用户数组时发现了问题。在API中,它们是双引号,但被放在引号中,因此它将其作为字符串读取。我已经意识到了这个问题,并编写了代码将它们从Strings转换为Doubles。但是,我把它放在代码的.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()
            }

我意识到这可能不是最好或唯一的解决方案,但它解决了我的问题。我希望这能对其他人有所帮助。再次感谢。

在回调中有大量可选的展开,其中任何一个都可能为零。您需要进入调试器并检查返回的JSON。如果调试器有困难,可以在尝试使用JSON变量并查看其内容之前打印((该变量。

提示:不要在类属性上使用隐式展开的可选类型。这不是一种安全的做法。如果您不打算在创建类实例后修改属性,请使用let name:String作为实例,而不是var name:String!。让编译器帮助您编写正确的程序。

最新更新