Swift / Alamofire: итерация значений JSON для проверки значения bool? - PullRequest
0 голосов
/ 24 декабря 2018

Вот JSON:

 {
  "data": [
    {
      "type": "season",
      "id": "season.1",
      "attributes": {
        "isCurrentSeason": true,
        "isOffseason": false
      }
    },
    {
      "type": "season",
      "id": "season2",
      "attributes": {
        "isCurrentSeason": false,
        "isOffseason": false
      }
    }
}

Я пытаюсь перебрать эти данные JSON, чтобы проверить, является ли isCurrentSeason истиной.Если это правда, мне нужно сохранить его «id».

Вот моя текущая реализация:

Alamofire.request(request).responseJSON { response in
            switch response.result {

            case .Success(let _data):
                print(_data)
                if let DataObject = _data["data"] as? NSDictionary {
                    if let Attributes = DataObject["attributes"] as? [NSDictionary] {
                        for attribute in Attributes {
                            if Attributes["isCurrentSeason"] = true {
                                currentSeasonID = Attributes["isCurrentSeason"]
                            }
                        }
                    }
                }
            default:
                break;
            }
        }

Я продолжаю получать ошибку Pattern cannot match values of type 'Result<Any>' в случае. Строка успеха.Так что я даже не могу проверить, вытягивает ли он правильные данные.Не уверен, что есть лучший способ перебора и записи данных.

Ответы [ 3 ]

0 голосов
/ 24 декабря 2018

Прежде всего вы не должны использовать NSDictionary вместо Dictionary Свифта.Во-вторых, вы не используете data с тем же типом, который возвращается в ответе.Это должно быть array из dictionary, пока вы разыгрываете его как dictionary, где оно всегда будет терпеть неудачу.Я не уверен, какую версию Alamofire вы используете, но в текущей версии enum Result<Any> success case - camelCase, т.е. .success(let data).Если вы получили ошибку, используйте уже имеющуюся, то есть .Success(let data).Ниже исправлена ​​версия,

Alamofire.request(request).responseJSON { response in
    typealias JSON = [String: Any]
    switch response.result {
    case .success(let data):
        guard let json = data as? JSON, let objects = json["data"] as? [JSON] else { return }
        for object in objects {
            if let attributes = object["attributes"] as? JSON,
                let currentSession = attributes["isCurrentSeason"] as? Bool,
                currentSession == true {
                print(currentSession)
                print(object["id"] as! String)
                break
            }
        }
    default:
        print("Error occured")
    }
}
0 голосов
/ 24 декабря 2018

Ошибка ясно говорит о том, что _data - кстати, переменные с начальным подчеркиванием очень target-c-ish - это Any, поэтому вы должны условно понижать уже этот тип.если ожидаемый тип является словарем, рассмотрите возможность использования более конкретной Result<[String:Any]>.

Пожалуйста, прочитайте JSON.Это довольно легко.Существует только два типа коллекции: массив ([]) и словарь ({}), поэтому значение для ключа data является массивом, а значение для ключа attributes является словарем

ИПожалуйста, соблюдайте соглашение об именах, что переменные начинаются со строчной буквы и не используют NSArray и NSDictionary в Swift.

switch response.result {

        case .Success(let response):

            if let response = response as? [String:Any],
               let data = response["data"] as? [[String:Any]] {
               for item in data {
                   if let attributes = item["attributes"] as? [String:Bool],
                      let isCurrentSeason = attributes["isCurrentSeason"], isCurrentSeason == true {
                         currentSeasonID = isCurrentSeason
                         break // add this to exit the loop immediately if the item was found
                   }
               }
            }
        default:
            break
        }

Однако я предполагаю, что currentSeasonID должен быть id значение вместо логического isCurrentSeason

        case .Success(let response):

            if let response = response as? [String:Any],
               let data = response["data"] as? [[String:Any]] {
               for item in data {
                   if let identifier = item["id"] as? String,
                      let attributes = item["attributes"] as? [String:Bool],
                      let isCurrentSeason = attributes["isCurrentSeason"], isCurrentSeason == true {
                         currentSeasonID = identifier
                         break // add this to exit the loop immediately if the item was found
                   }
               }
            }
        default:
            break
        }
0 голосов
/ 24 декабря 2018

Вы можете попробовать

if let content =  _data as? [String:Any] {
    if let dataObject = content["data"] as? [[String:Any]] {
            dataObject.forEach {
             if let attributes = $0["attributes"] as? [String:Bool] { 
                if attributes["isCurrentSeason"] == true { 
                    print("This is true")
                }
            }
        }
    }
}

Ваш data является массивом словарей, а attributes является словарем

...