2016-09-20 2 views
1

Ich habe gerade mein Projekt von Swift 2.2 auf 3.0 konvertiert, und ich bekomme eine neue Ausnahme in meinen Tests geworfen. Ich habe einige Objective-C-Code in einem meiner Tests, die aus einer Datei in einigen JSON liest:Swift 3 NSDictionary to Dictionary Konvertierung verursacht NSInvalidArgumentException

+ (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; 
} 

ich dies von einem Swift-Code aufrufen:

let expectedResponseJSON = BZTestCase.getJSONDictionary(fromFile: responseFileName) 

Das funktioniert just fine meisten der Zeit, aber ich habe eine JSON-Datei, die den Fehler verursacht:

failed: caught "NSInvalidArgumentException", "-[__NSSingleObjectArrayI enumerateKeysAndObjectsUsingBlock:]: unrecognized selector sent to instance 0x608000201fa0" 

das merkwürdige daran ist, dass der Fehler ein erzeugt wird nach der getJSONDictionaryFromFile Methode kehrt zurück und vor expectedResponseJSON im Swift-Code ist bestückt. Für mich scheint dies zu sagen, dass es die Konvertierung von NSDictionary zu Dictionary ist, die das Problem ist. Die fehlbare JSON-Datei ist diese:

[ 
    { 
    "status": "403", 
    "title": "Authentication Failed", 
    "userData": {}, 
    "ipRangeError": { 
     "libraryName": "Name goes here", 
    "libraryId": 657, 
     "requestIp": "127.0.0.1" 
    } 
    } 
] 

Wenn ich die äußersten umschließenden [], diese Fehler gehen weg entfernen. Ich kann nicht die einzige Person sein, die ein Array als Top-Level-Entity einer JSON-Datei in Swift 3 verwendet, mache ich etwas falsch? Was kann ich tun, um diesen Fehler zu umgehen?

+0

Natürlich können Sie ein Array als das oberste JSON-Objekt verwenden. Aber dann müssen Sie es als ein Array behandeln, nicht als ein Wörterbuch. –

Antwort

4

Wie in den Kommentaren verwiesen wird, ist das Problem, dass getJSONDictionaryFromFile eine NSDictionary * zurückgibt und meine JSON-Eingabe ist ein Array. Das einzige Rätsel ist, warum dies in Swift 2.2 funktioniert hat! Ich landete expectedResponseJSON Wechsel bis zu einem Any? sein, und schrieb meine Objective C-Code in Swift:

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 
} 

Als Hinweis für alle, die diesen Code könnte Ausschneiden und Einfügen, benutzen ich try! und filepath! statt try? und if let... weil Dieser Code wird ausschließlich in Tests verwendet, daher möchte ich, dass er so schnell wie möglich abstürzt, wenn meine Eingaben nicht den Erwartungen entsprechen, die ich von ihnen erwarte.

Verwandte Themen