JSON序列化错误
我从一个生成json数组的php脚本中提取数据。 iOS更新后,我的jsonserialization崩溃的应用程序。 json应该根据jsonformatter.org和freeformatter.com/json-validator.html(符合RFC4627)进行良好的组织。 这是代码。 任何帮助是极大的赞赏!
func parseJSON() { var jsonResult: NSMutableArray = NSMutableArray() do{ jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSMutableArray } catch let error as NSError { print(error) } var jsonElement: NSDictionary = NSDictionary() let locations: NSMutableArray = NSMutableArray() for i in 0 ..< jsonResult.count { jsonElement = jsonResult[i] as! NSDictionary let location = LocationModel() //the following insures none of the JsonElement values are nil through optional binding if let id = jsonElement["id"] as? String, let oprettelsesdato = jsonElement["oprettelsesdato"] as? String, let overskrift = jsonElement["overskrift"] as? String, let address = jsonElement["address"] as? String, let intro = jsonElement["intro"] as? String, let email = jsonElement["email"] as? String, let tlf = jsonElement["tlf"] as? String, let annonce = jsonElement["annonce"] as? String, let journalnr = jsonElement["journal"] as? String { location.id = id location.oprettelsesdato = oprettelsesdato location.overskrift = overskrift location.address = address location.intro = intro location.email = email location.tlf = tlf location.annonce = annonce location.journalnr = journalnr } locations.add(location) } DispatchQueue.main.async(execute: { () -> Void in //print("Check home") self.delegate.itemsDownloaded(locations) }) }
系统崩溃日志:
objc[1285]: Class PLBuildVersion is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/AssetsLibraryServices.framework/AssetsLibraryServices (0x11799a998) and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/PhotoLibraryServices (0x1177bc880). One of the two will be used. Which one is undefined. Could not cast value of type '__NSArrayI' (0x105f1ed88) to 'NSMutableArray' (0x105f1ee50).
更新我现在使用vadians解决scheme,但是,而不是self.delegate.itemsDownloaded(地点),我使用self.delegate.itemsDownloaded(地点作为NSArray)。
但是,所有jsonElements现在都是零。 它获得数组中正确数量的元素,但如果我打印它的所有值是零:
( "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil", "id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil" )
这里是我尝试检索数据的地方。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let item: LocationModel = feedItems[indexPath.row] as! LocationModel let cellIdentifier: String = "BasicCell" let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)! //myCell.detailTextLabel!.text = item.oprettelsesdato myCell.textLabel!.text = item.overskrift myCell.textLabel!.leadingAnchor.constraint(equalTo: myCell.leadingAnchor).isActive = true myCell.textLabel!.topAnchor.constraint(equalTo: myCell.topAnchor).isActive = true myCell.textLabel!.heightAnchor.constraint(equalTo: myCell.heightAnchor, multiplier: 1.0).isActive = true myCell.textLabel!.widthAnchor.constraint(equalTo: myCell.heightAnchor, multiplier: 0.8).isActive = true //print(item.id) <-returns nil //print(item.oprettelsesdato) <-returns nil //print(item.overskrift) <-returns nil extralabel!.text = item.oprettelsesdato // <-This is where the error is thrown extralabel!.textColor = UIColor.white myCell.contentView.addSubview(extralabel!) //some more stuff... }
错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
不知道发生了什么问题。 有什么build议么?
对于你的问题至关重要的是这个部分as! NSMutableArray
as! NSMutableArray
:
jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSMutableArray
即使在较老的iOS中,将NSJSONSerialization.JSONObjectWithData
的结果转换为NSMutableArray
也不是保证操作 (当您不指定.mutableContainers
选项时)。
看到你的整个代码,你不会突变jsonResult
,所以你可以使用一个简单的NSArray
而不是NSMutableArray
:
var jsonResult: NSArray = NSArray() do{ jsonResult = try JSONSerialization.jsonObject(with: self.data as Data) as! NSArray } catch let error as NSError { print(error) }
我build议你使用Swifttypes,比如Data
, Array
或者Dictionary
,而不是NSData
, NSArray
( NSMutableArray
)或者NSDictionary
。 但是这对你来说并不重要。
请让我重复一下我的评论:
不要 – 永远不要 – 在Swift中使用NSMutable...
集合types。
它们与Swift收集types无关,并导致所有问题。 var
关键字使得任何Swift对象都是可变的,非常容易使用。 除此之外,接收的数组在您的代码中完全没有发生变异。
可悲的是,build议NSMutable...
的一半知识教程永远不会消失:
在Swift 3
- 一个JSON字典是
[String:Any]
- 一个JSON数组是
[[String:Any]]
或[Any]
由于JSON对象应该是一个数组.allowframents
是相当无用的。
所以:
func parseJSON() { var jsonResult = [[String:Any]]() do{ jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:[]) as! [[String:Any]] } catch { print(error) return } var locations = [LocationModel]() for jsonElement in jsonResult { // no ugly C-style index based loops! let location = LocationModel() //the following insures none of the JsonElement values are nil through optional binding if let id = jsonElement["id"] as? String, let oprettelsesdato = jsonElement["oprettelsesdato"] as? String, let overskrift = jsonElement["overskrift"] as? String, let address = jsonElement["address"] as? String, let intro = jsonElement["intro"] as? String, let email = jsonElement["email"] as? String, let tlf = jsonElement["tlf"] as? String, let annonce = jsonElement["annonce"] as? String, let journalnr = jsonElement["journal"] as? String { location.id = id location.oprettelsesdato = oprettelsesdato location.overskrift = overskrift location.address = address location.intro = intro location.email = email location.tlf = tlf location.annonce = annonce location.journalnr = journalnr } locations.append(location) } DispatchQueue.main.async { //print("Check home") self.delegate.itemsDownloaded(locations) } }
注意:如果jsonElement
只包含string,你甚至可以将字典转换为[String:String]
并将其全部清除掉 as? String
as? String
转换。
我build议创build一个可选的init方法,它接受json并尝试创buildLocationModel
。
struct LocationModel { var id: String var oprettelsesdato: String var overskrift: String var address: String var intro: String var email: String var tlf: String var annonce: String var journalnr: String init?(json: [String:Any]) { guard let id = json["id"] as? String, let oprettelsesdato = json["oprettelsesdato"] as? String, let overskrift = json["overskrift"] as? String, let address = json["address"] as? String, let intro = json["intro"] as? String, let email = json["email"] as? String, let tlf = json["tlf"] as? String, let annonce = json["annonce"] as? String, let journalnr = json["journal"] as? String else { return } self.id = id self.oprettelsesdato = oprettelsesdato self.overskrift = overskrift self.address = address self.intro = intro self.email = email self.tlf = tlf self.annonce = annonce self.journalnr = journalnr } }
然后,在parseJSON
函数中,而不是使用NSMutableArray
,可以使用[LocationModel]
。 这样,我们可以使用json.flatMap { LocationModel(json: $0) }
将json元素数组( [[String:Any]]
)直接json.flatMap { LocationModel(json: $0) }
到[LocationModel]
。
func parseJSON() { var locations = [LocationModel]() do{ if let json = try JSONSerialization.jsonObject(with: data as Data, options: []) as? [[String:Any]] { locations = json.flatMap { LocationModel(json: $0) } } } catch let error as NSError { print(error) } DispatchQueue.main.async { self.delegate.itemsDownloaded(locations) } }
- Swift JSON错误:无法将types'__NSDictionaryM'的值转换为'NSArray'
- SpriteKit / Swift – 当两个节点已经联系时如何检查两个节点的联系
- 如何使用联系人与Swiftsorting联系人
- 在swift中parsing对象内的json数组
- Swift中的分配工具工具没有提供足够详细的信息
- 数据input自定义视图的Swift示例(自定义应用程序内键盘)
- Swift + Locksmith:没有获取存储的钥匙串值
- 自定义input视图作为Swift中使用OSX 10.9和Xcode 6.1.1 +的文本字段的键盘
- Swift:如何从NSScanner的AutoreleasingUnsafePointer <NSString?>中获取值?