【问题标题】:Converting NSArray to Array in Swift produces nil to the Array Values在 Swift 中将 NSArray 转换为数组会产生 nil 到数组值
【发布时间】:2019-11-22 09:22:00
【问题描述】:

我遇到了一些我认为很简单的问题,但不知何故我想不出任何方法来解决它。它只是将一个 NSArray 转换为一个数组,我认为我在这里用这段代码做得很好:

func getTrainingSubCategories(completion: @escaping(Result<[TrainingSubCategory], GetError>) -> Void){
    let dataTask = URLSession.shared.dataTask(with: resourceURL){data, _, _ in
        guard let jsonData = data else {
            completion(.failure(.trainingCategoriesNoDataAvailable))
            return
        }
        do{
            let parsedData = try JSONSerialization.jsonObject(with: jsonData) as! [String: Any]
            for (key, value) in parsedData {
                if key == "categories" {
                    if let categoriesDictionary: [[String: Any]] = value as? [[String: Any]]{
                        for categoryDictionary in categoriesDictionary{
                            for (key, value) in categoryDictionary{
                                if key == "sub_categories" {
                                    print("1st Type => \(type(of: value)) Value => \(value)")
                                    print("2nd Type => \(type(of: value as? Array<TrainingSubCategory>)) Value => \(value as? Array<TrainingSubCategory>)")
//                                        guard let subCategoryValue = value as? Array<TrainingSubCategory> else{
//                                            fatalError("Error in casting value to array of trainingsubcategory")
//                                        }
                                }
                            }
                        }
                    }
                }
            }
        }catch {
            completion(.failure(.trainingSubCategoriesCannotProcessData))
        }

    }
    dataTask.resume()
}

但控制台会记录其他情况:

1st Value => (
        {
        "category_id" = 1;
        "company_id" = 50;
        "created_at" = "2019-11-07 00:58:37";
        "deleted_at" = "<null>";
        id = 1;
        name = Advertisement;
        "updated_at" = "2019-11-07 00:58:37";
    },
        {
        "category_id" = 1;
        "company_id" = 50;
        "created_at" = "<null>";
        "deleted_at" = "<null>";
        id = 3;
        name = Sales;
        "updated_at" = "2019-11-10 23:28:30";
    }
)
2nd Value => nil
1st Value => (
        {
        "category_id" = 2;
        "company_id" = 50;
        "created_at" = "2019-11-07 19:58:07";
        "deleted_at" = "<null>";
        id = 6;
        name = Inventory;
        "updated_at" = "2019-11-07 19:58:07";
    }
)
2nd Value => nil
1st Value => (
        {
        "category_id" = 3;
        "company_id" = 50;
        "created_at" = "2019-11-10 21:24:22";
        "deleted_at" = "<null>";
        id = 9;
        name = "Human Resource";
        "updated_at" = "2019-11-10 21:24:22";
    }
)
2nd Value => nil

我在这里遗漏了什么吗?我对 Swift 很陌生,所以我自己实际上并没有太多猜测。

【问题讨论】:

  • 您的 TrainingSubCategory 类/结构是否符合 Codable 协议?
  • 您不能将值转换为特定类型的数组,您需要手动将字典映射到您的自定义类型 TrainingSubCategory。正如前面的评论所暗示的那样,也许最简单的方法是向我们Codable 解码您的 json
  • 这不是TrainingSubCatgory 的数组,而是字典的数组。它不被解析为 TrainingSubCatgory,它是字典。
  • @KeshuRai,是的。 :)
  • @JoakimDanielson,我已经让它可编码了。我按照你说的做了,手动将其映射到 TrainingSubCategory。它工作得很好,谢谢!我会显示代码

标签: arrays json swift dictionary nsarray


【解决方案1】:

所以我将返回类型设置为一个简单的 NSDictionary 数组。

func getTrainingSubCategories(completion: @escaping(Result<[NSDictionary], GetError>) -> Void){
    let dataTask = URLSession.shared.dataTask(with: resourceURL){data, _, _ in
        guard let jsonData = data else {
            completion(.failure(.trainingCategoriesNoDataAvailable))
            return
        }
        var trainingSubCategories = [NSDictionary]()
        do{
            let parsedData = try JSONSerialization.jsonObject(with: jsonData) as! [String: Any]
            for (key, value) in parsedData {
                if key == "categories" {
                    if let categoriesDictionary: [[String: Any]] = value as? [[String: Any]]{
                        for categoryDictionary in categoriesDictionary{
                            for (key, value) in categoryDictionary{
                                if key == "sub_categories" {
                                    if let subCategoriesArray: [Any] = value as? [Any] {
                                        for subCategory in subCategoriesArray{
                                            trainingSubCategories.append(subCategory as! NSDictionary)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                completion(.success(trainingSubCategories))
            }
        }catch {
            completion(.failure(.trainingSubCategoriesCannotProcessData))
        }
        
    }
    dataTask.resume()
}

我的函数调用返回如下所示:

private func downloadSubCategories(withCompanyID: Int) {
    let trainingCategoriesRequest = GetRequests(endpoint: "getTrainingCategories", id: String(withCompanyID))
    trainingCategoriesRequest.getTrainingSubCategories{result in
        switch result{
        case .success(let trainingSubCategories):
            for counter in 0 ..< trainingSubCategories.count {
                for (key, value) in trainingSubCategories[counter]{
                    print("\(key) => \(value)")
                }
            }
        case .failure(let error):
            print(error)
        }
    }
}

我能够在不将 NSDictionary 转换为 TrainingSubCategory 的情况下映射它们。很抱歉,您将查看该帖子,这不是对最初问题的回答,而是一种解决方法。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 2012-02-24
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    相关资源
    最近更新 更多