невозможно получить доступ к массиву JSON в Swift - PullRequest
0 голосов
/ 07 мая 2018

У меня есть файл JSON, и я пытаюсь получить доступ к массиву в нем.

Файл JSON выглядит следующим образом:

{
 "cars": [{
                    "name": "BMW",
                    "icons": [["front.png", "back.png", "B3"],
                              ["front_red", "back_red", "C4"]
                             ]
           }]
}

// cars это массив словарей, я только что упомянул один из них.

Я получаю данные JSON как:

func loadJSONData(){

        if let path = Bundle.main.path(forResource: "testJSON", ofType: "json")
        {
            if let jsonData = NSData(contentsOfFile : path)
            {
                do {
                    if let jsonResult = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any]
                    {
                        self.testJSONData = (jsonResult["cars"] as? Array)! 
                        //self.testJSONData = (jsonResult["cars"] as? Array<Dictionary<String, Any>>)!    //also tried this
                    }

                }
                catch let error as NSError {
                    print(error.localizedDescription)
                }
            }
        }
    }

testJSONData объявляется как массив:

var testJSONData = [] as [Dictionary<String, Any>]

и ошибка возникает при попытке получить массив "icons" из JSON.

let namePredicate = NSPredicate(format: "name like BMW")
let filteredArray :Array = testJSONData.filter() { namePredicate.evaluate(with: $0) }
let carData: Dictionary = filteredArray[0] as Dictionary<String, Any>
let carIcons: Array = carData["icons"] as! Array //error at this line

Невозможно преобразовать значение типа 'Array <_>' в указанный тип 'Array'

Может кто-нибудь показать мне, где я не так делаю? Спасибо!

1 Ответ

0 голосов
/ 07 мая 2018

Array является универсальным типом в Swift, поэтому, когда вы хотите объявить переменную массива, вам всегда нужно указать, какой тип элементов содержит Array. Нет такого типа как Array без указания типа Element.

Кроме того, нет необходимости в аннотациях типов в Swift, компилятор может вывести типы для вас, и вы явно указываете компилятору тип, приводя в любом случае приведение.

carIcons должен быть типа Array<Array<String>> или как сокращение [[String]]

let carIcons = carData["icons"] as! [[String]]

Некоторые общие замечания о вашем коде: не используйте старые типы Foundation, такие как NSData в Swift, когда они имеют собственные эквиваленты Swift. Также не делайте принудительного развертывания безопасных типов, это не имеет смысла. Либо справляйтесь с распаковкой и безопасно, либо просто принудительно разыгрывайте, если вы точно знаете, что приведение будет успешным. .mutableContainers не имеют никакого эффекта в Swift, поэтому не используйте его. Нет необходимости приводить error к NSError в блоке захвата, у Swift есть свой собственный тип Error.

func loadJSONData(){
    if let fileURL = Bundle.main.url(forResource: "testJSON", withExtension: "json") {
        do {
            let jsonData = try Data(contentsOfFile: fileURL)
            if let jsonResult = try JSONSerialization.jsonObject(with: jsonData) as? [String:Any], let cars = jsonResult["cars"] as? [[String:Any]] {
                self.testJSONData = cars
            } else {
                print("Unexpected JSON format")
            }
        }
        catch {
            print(error)
        }
    }
}

Однако, если вы используете Swift 4, лучшим решением было бы использование протокола типа * Codable и JSONDecoder вместо JSONSerialization.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...