Swift 3 NSDictionary 到 Dictionary 的转换导致 NSInvalidArgumentException
Posted
技术标签:
【中文标题】Swift 3 NSDictionary 到 Dictionary 的转换导致 NSInvalidArgumentException【英文标题】:Swift 3 NSDictionary to Dictionary conversion causes NSInvalidArgumentException 【发布时间】:2016-09-20 13:54:00 【问题描述】:我刚刚将我的项目从 Swift 2.2 转换为 3.0,并且在我的测试中抛出了一个新异常。我的一个测试中有一些 Objective C 代码,它从文件中读取一些 JSON:
+ (NSDictionary *)getJSONDictionaryFromFile:(NSString *)filename
/* some code which checks the parameter and gets a string of JSON from a file.
* I've checked in the debugger, and jsonString is properly populated. */
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
return jsonDict;
我从一些 Swift 代码中调用它:
let expectedResponseJSON = BZTestCase.getJSONDictionary(fromFile: responseFileName)
这大部分在大多数情况下都可以正常工作,但我有一个导致错误的JSON
文件:
failed: caught "NSInvalidArgumentException", "-[__NSSingleObjectArrayI enumerateKeysAndObjectsUsingBlock:]: unrecognized selector sent to instance 0x608000201fa0"
奇怪的是,错误是在getJSONDictionaryFromFile
方法返回之后,在Swift代码中expectedResponseJSON
被填充之前产生的。对我来说,这似乎是从NSDictionary
到Dictionary
的转换,这就是问题所在。有问题的 JSON 文件是这个:
[
"status": "403",
"title": "Authentication Failed",
"userData": ,
"ipRangeError":
"libraryName": "Name goes here",
"libraryId": 657,
"requestIp": "127.0.0.1"
]
如果我删除最外层的[]
,这个错误就会消失。我不能是唯一一个在 Swift 3 中使用数组作为 JSON 文件的***实体的人,我做错了什么吗?我可以做些什么来解决这个错误?
【问题讨论】:
当然可以使用数组作为***JSON对象。但是你必须把它当作一个数组,而不是一个字典。 【参考方案1】:正如 cmets 中所引用的,问题在于 getJSONDictionaryFromFile
返回一个 NSDictionary *
而我的 JSON 输入是一个数组。唯一的谜团是为什么它曾经在 Swift 2.2 中工作!我最终将expectedResponseJSON
更改为Any?
,并用Swift 重写了我的Objective C 代码:
class func getStringFrom(file fileName: String, fileExtension: String) -> String
let filepath = Bundle(for: BZTestCase.self).path(forResource: fileName, ofType: fileExtension)
return try! NSString(contentsOfFile: filepath!, usedEncoding: nil) as String
class func getJSONFrom(file fileName: String) -> Any?
let json = try! JSONSerialization.jsonObject(with: (getStringFrom(file: fileName, fileExtension: ".json").data(using: .utf8))!, options:.allowFragments)
return json
作为对可能剪切和粘贴此代码的任何人的说明,我使用 try!
和 filepath!
而不是 try?
和 if let...
,因为此代码专门用于测试,所以我希望它崩溃为如果我的输入不是我所期望的,请尽快。
【讨论】:
以上是关于Swift 3 NSDictionary 到 Dictionary 的转换导致 NSInvalidArgumentException的主要内容,如果未能解决你的问题,请参考以下文章
Swift:将 NSDictionary 保存到文件中,因为 NSUserDefaults 会变慢
swift里nsdictionary和dictionary有啥区别
不能使用 String 类型的索引为 NSDictionary 类型的值下标。从 Swift 2.3 -> 3.2 转换时
如何将所有键和值从 Swift 中的 NSDictionary 获取到单独的字符串数组中?