Swift 2.0:无法将类型“__NSArrayM”(0x10a9348d8)的值转换为“NSDictionary”(0x10a934d60)

Posted

技术标签:

【中文标题】Swift 2.0:无法将类型“__NSArrayM”(0x10a9348d8)的值转换为“NSDictionary”(0x10a934d60)【英文标题】:Swift 2.0: Could not cast value of type '__NSArrayM' (0x10a9348d8) to 'NSDictionary' (0x10a934d60) 【发布时间】:2015-11-11 15:14:17 【问题描述】:

我一直在阅读一些对类似问题的问题的回复,但我就是想不通......

我有 PostService,它执行 JSON POST 请求并从 mysql 数据库中获取数据。在我转换到 Swift 2.0 之前一切正常,现在它给了我装备。 (代码来自 Skip Wilson 的 Youtube 系列 - Swift: Using External Databases and API's)

它在输出中给出上述错误并停止并突出显示这一行 -

"让 response = (try!NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as!NSDictionary"

var settings:Settings!

init() 
    self.settings = Settings()


let userLoginEmail = "admin@email.co.za"; 
let userLoginPassword = "1234";            

func getPosts(callback:(NSDictionary) -> ()) 
    request(settings.viewPosts, callback: callback) 


func request(url:String, callback:(NSDictionary) -> ()) 

    let myURL = NSURL(string: url)
    let requested = NSMutableURLRequest(URL:myURL!);
    requested.HTTPMethod = "POST";

    let postString = "email=\(userLoginEmail)&password=\(userLoginPassword)";

    print("email=\(userLoginEmail)&password=\(userLoginPassword)")

    requested.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);

    let task = NSURLSession.sharedSession().dataTaskWithRequest(requested) 
        (data, response, error) in

   let response = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary

        callback(response)
    
    task.resume()

这是我的 JSON 帖子...以我有限的知识和在 json.org 上的阅读,它看起来像一个对象,里面有一个包含一堆对象的数组(字典?)所有这些的格式都没有更改,我的应用程序将从数据库中获取数据并在转换之前正确显示它..

"posts":["Post":"Id":"5","idno":"4","product":"Aspen Simvastatin","quantity":"30","due_date":"2015-04-11","last_repeat":"2015-04-10","doctor":"Dr. Jim Jones","store":"Central","currentrepeat":"2","totalrepeat":"6","active_ingredient":"Simvastatin","strength":"20mg","manufacturer":"Aspen Pharmacare","dosage_form":"Tabs","directions":"Take one tablet daily","repeatflag":"0","repeattimestamp":"2015-08-17 20:38:13","Post":"Id":"6","idno":"4","product":"Mybulen","quantity":"45","due_date":"2015-04-11","last_repeat":"2015-04-10","doctor":"Dr. Jim Jones","store":"Central","currentrepeat":"3","totalrepeat":"6","active_ingredient":"Codeine Phosphate;Ibuprofen;Paracetamol","strength":"10mg;200mg;250mg","manufacturer":"Aspen Pharmacare","dosage_form":"Tabs","directions":"Take one or two tablets four times a day after meals","repeatflag":"0","repeattimestamp":"2015-08-17 20:38:13","Post":"Id":"7","idno":"4","product":"Ecotrin XL","quantity":"30","due_date":"2015-04-11","last_repeat":"2015-03-11","doctor":"Dr. Jim Jones","store":"Central","currentrepeat":"4","totalrepeat":"6","active_ingredient":"Aspirin","strength":"81mg","manufacturer":"Litha Pharma","dosage_form":"Tabs","directions":"Take one tablet in the morning","repeatflag":"0","repeattimestamp":"2015-08-17 20:38:13","Post":"Id":"8","idno":"4","product":"Lorien","quantity":"28","due_date":"2015-04-11","last_repeat":"2015-03-11","doctor":"Dr. J. Eckel","store":"Central","currentrepeat":"4","totalrepeat":"6","active_ingredient":"Fluoxetine HCl","strength":"20mg","manufacturer":"Aspen Pharmacare","dosage_form":"Caps","directions":"Take one capsule in the morning","repeatflag":"0","repeattimestamp":"2015-08-17 20:38:13"]

如果能提供任何帮助,我将不胜感激。

在我的 masterViewController 的 viewDidLoad() 中,我有这段代码处理获取的信息...

      service = PostService()
    service.getPosts 
        (response) in
        self.loadPosts(response["posts"]! as! NSArray)
    



func loadPosts(posts:NSArray) 
    for post in posts 
        let post = post["Post"]! as! NSDictionary
        let Id = Int((post["Id"]! as! String))!
        let idno = Int((post["idno"]! as! String))!
        let product = post["product"]! as! String
        let quantity = Int((post["quantity"]! as! String))!
        let doctor = post["doctor"]! as! String
        let store = post["store"]! as! String
        let currentrepeat = Int((post["currentrepeat"]! as! String))!
        let totalrepeat = Int((post["totalrepeat"]! as! String))!
        let active_ingredient = post["active_ingredient"]! as! String
        let strength = post["strength"]! as! String
        let manufacturer = post["manufacturer"]! as! String
        let dosage_form = post["dosage_form"]! as! String
        let directions = post["directions"]! as! String
        let postObj = Post(Id: Id, idno: idno, product: product, quantity: quantity, doctor: doctor, store: store, currentrepeat: currentrepeat, totalrepeat: totalrepeat, active_ingredient: active_ingredient, strength: strength, manufacturer: manufacturer, dosage_form: dosage_form, directions: directions)
        postsCollection.append(postObj)
        dispatch_async(dispatch_get_main_queue()) 
            self.tableView.reloadData()
        
    

【问题讨论】:

突出显示的行没有出现在您发布的代码中?!? 谢谢@***foe - 必须是剪切而不是复制.. 您是否确定这是您尝试处理的 JSON? 错误信息说,结果是数组,不是字典 不...您确定您发布的 JSON 确实是您收到的内容吗?例如,可能会在错误或类似情况下返回不同的结构。 【参考方案1】:

您是在告诉 NSJSONSerialization,您绝对确定 JSON 可以被解析,并且您希望您的应用程序崩溃,如果它没有。 (这就是尝试!)。好吧,在很多情况下,您要求 JSON 并且您得到了 html,因此您的用户不会对此感到满意,假设他们是否在酒店或最近的星巴克使用您的应用程序。

接下来,您要告诉 NSJSONSerialization,您完全确定 JSON 包含字典,并且如果不包含字典,您希望您的应用程序崩溃(如!NSDictionary)。你猜怎么着,你得到了一个数组。您最好阅读您的 API 文档,并检查此处给出的内容。

顺便说一句。我不在乎您发布的内容是您应该得到的 JSON - 我知道您收到了一个数组。不相信?调试的第一条规则:你知道的是错误的。

【讨论】:

以上是关于Swift 2.0:无法将类型“__NSArrayM”(0x10a9348d8)的值转换为“NSDictionary”(0x10a934d60)的主要内容,如果未能解决你的问题,请参考以下文章

Swift 2.0:使用 Set 时无法将值 MyApp.MyCustomClass 转换为 MyAppTests.MyCustomClass

Swift 2.0:无法将类型“__NSArrayM”(0x10a9348d8)的值转换为“NSDictionary”(0x10a934d60)

Swift 2.0:推断闭包类型错误

如何从 Swift 2.0 中获取子数组

iOS 9(Swift 2.0):无法使用类型为“(NSURL,(_,_,_)throws-> Void)”的参数列表调用“dataTaskwithURL”

核心数据和数组 swift 2.0