简体   繁体   English

尝试将AlamoFire JSON响应映射到类并收到“致命错误:在展开可选包时意外发现nil”

[英]Trying to map an AlamoFire JSON response to a Class and receiving “Fatal Error: Unexpectedly found nil while unwrapping optional”

I am using AlamoFire to pull my API to populate the cells of my tableView. 我正在使用AlamoFire提取API来填充tableView的单元格。 The app is able to Build, but crashes soon after with the customary "Fatal Error: unexpectedly found nil while unwrapping an Optional value." 该应用程序可以构建,但随后会因惯常的“致命错误:在展开可选值时意外发现nil”而崩溃。 I've gone over all my optional values and can't figure out which one is causing the problem. 我已经检查了所有可选值,无法确定是哪个引起了问题。 Xcode says the problem comes during the .map portion of AlamoFire. Xcode表示问题出在AlamoFire的.map部分。 Any help would be appreciated. 任何帮助,将不胜感激。

Before I get to the code, one of the values in my JSON is null for every key (I didn't write the JSON). 在获得代码之前,JSON中的每个键值之一都是空的(我没有写JSON)。 It's not "null", just null. 它不是“ null”,而是null。 Could this be causing the problem even though I'm not mapping that key to my Class? 即使我没有将该键映射到我的班级,这是否可能会导致问题?

The JSON is an Array of Dictionaries. JSON是字典数组。 After making the .GET request, I'm taking the JSON response and mapping it to a variable that I initialized as an Array of Class types. 发出.GET请求后,我将获取JSON响应并将其映射到我初始化为Class类型数组的变量。

Here is the code: 这是代码:

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()

    }

And here is the Class type from my User.swift: 这是我的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"


}

I've read in some help sections that I might not be initializing the instance of my class correctly, but I've tried every combination to no avail. 在某些帮助部分中,我读到了我可能无法正确初始化类实例的信息,但是我尝试了每种组合都无济于事。 I've also tried playing with NSMutableDictionary, but that didn't fix anything. 我也尝试过与NSMutableDictionary一起玩,但这并不能解决任何问题。

Thank you everyone for your responses. 谢谢大家的答复。 They were all very helpful. 他们都非常有帮助。

I shortened parts of my code to the essentials when I shared it above, but the problem was found in mapping the var lat and var lon to my user array. 当我在上面共享代码时,我将代码的一部分简化为基本要点,但是在将var latvar lon映射到我的用户数组时发现了问题。 In the API they were doubles, but were put in quotation marks, so it was reading it as a String. 在API中,它们是双精度的,但是用引号引起来,因此将其读取为String。 I had realized the problem and wrote code to convert them from Strings to Doubles. 我已经意识到了这个问题,并编写了将其从Strings转换为Doubles的代码。 However, I put that in the .map{} portion of my code (not seen above). 但是,我将其放在代码的.map{}部分中(上面没有看到)。 There may be a way to do this there, but it never worked for me. 那里可能有一种方法可以执行此操作,但是它对我没有用。

Instead, I found my solution by changing my class User to make these changes as follows: 相反,我通过更改class User来进行以下更改,从而找到了解决方案:

let lat: String
let lon: String

var latDouble: Double
var lonDouble: Double

And then initialized it as follows: 然后将其初始化如下:

self.latDouble = (lat as NSString).doubleValue
self.lonDouble = (lon as NSString).doubleValue

I also incorporated SwiftyJSON to retrieve my API data and then filled my array as follows: 我还合并了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()
            }

I realize this might not be the best or only solution, but it solved my problem. 我意识到这可能不是最佳或唯一的解决方案,但它解决了我的问题。 I hope this might be helpful to someone else. 我希望这可能对其他人有所帮助。 Thanks again. 再次感谢。

There are tons of optionally getting unwrapped in your callback and any of them could be nil. 回调中有很多可选的解包方法,其中任何一个都可能为零。 You need to get in the debugger and inspect the JSON that came back. 您需要进入调试器并检查返回的JSON。 If you have difficulty with the debugger you could print() the JSON variable before trying to use it and see the contents. 如果您在调试器上遇到困难,则可以在尝试使用JSON变量并查看其内容之前将print()转换为JSON变量。

A tip: don't use implicitly unwrapped optional types on your class properties. 提示:不要在类属性上使用隐式展开的可选类型。 It's not a safe practice. 这不是安全的做法。 If you aren't going to modify a property after creating the class instance, use let name: String for instance instead of var name: String!. 如果在创建类实例后不打算修改属性,请使用let name:例如String代替var name:String!。 Let the compiler help you write a correct program. 让编译器帮助您编写正确的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Alamofire的Swift JSON-在展开可选值时意外发现nil - Swift JSON with Alamofire - Unexpectedly found nil while unwrapping an Optional value ARQuicklook-致命错误:展开一个可选值时意外发现nil - ARQuicklook - Fatal error: Unexpectedly found nil while unwrapping an Optional value 致命错误:在AVFoundation中解开Optional值时意外发现nil - fatal error: unexpectedly found nil while unwrapping an Optional value in AVFoundation 致命错误:展开一个可选值NSURL时意外发现nil - Fatal Error: Unexpectedly found nil while unwrapping an Optional value NSURL 致命错误:在展开可选值时意外发现 nil:文件 - Fatal error: Unexpectedly found nil while unwrapping an Optional value: file 致命错误:解开可选值计算时意外发现nil - fatal error: unexpectedly found nil while unwrapping an Optional value Computation WebView:致命错误:展开可选值时意外发现nil - WebView: fatal error: unexpectedly found nil while unwrapping an Optional value Swift:致命错误:在展开可选值时意外发现nil - Swift : fatal error: unexpectedly found nil while unwrapping an Optional value Swift-致命错误:解开Optional值时意外发现nil - Swift - Fatal error: unexpectedly found nil while unwrapping an Optional values 展开可选值时,意外发现致命错误nil [Firebase] - Fatal Error unexpectedly found nil while unwrapping an optional value [Firebase]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM