我刚刚将我的项目从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文件的顶级实体的人,我做错了什么?我该怎么做才能解决这个错误?
答案 0 :(得分:4)
正如评论中所引用的那样,问题是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...
,因为此代码仅用于测试,如果我的输入不是我期望的那样,我希望它尽快崩溃。