如何将嵌套数组添加到我的模型类

Posted

技术标签:

【中文标题】如何将嵌套数组添加到我的模型类【英文标题】:How to add Nested arrays to my model class 【发布时间】:2017-01-18 08:08:17 【问题描述】:

我从 API 收到以下响应。我需要将响应建模为 swift 3 中的类。 JSON 中的 Api 响应如下:


  "data": [
    
      "CategoryName": "אהבה",
      "CategoryID": "61",
      "CategoryDate": "2016-08-26 02:11:43",
      "CategoryImage": "love.png",
      "SubCategoryArray": [
        
          "SubCategoryName": "אהבה",
          "SubCategoryRefID": "61",
          "SubCategoryID": "115",
          "SubCategoryDate": "2016-08-29 09:25:56",
          "TextArray": [
            
              "TextID": "103",
              "Text": "<p dir=\"rtl\"><span style=\"font-size:48px\"><strong>אוהב</strong> אותך כל כך</span></p>\r\n"
            ,

如何为 subCategory 和 TextArray 子类建模。

我正在使用 SwiftyJSON 来填充我的模型类

我的模型类如下图;

class Menu

    var CategoryName: String?
    var CategoryID: String?
    var CategoryDate: String?
    var CategoryImage: String?
    var SubCategoryArray: [SubCategoryArray]?

    init(CategoryName: String?, CategoryID: String?, CategoryDate: String?, CategoryImage: String?, SubCategoryArray: [SubCategoryArray]?) 
        self.CategoryName = CategoryName
        self.CategoryID = CategoryID
        self.CategoryDate = CategoryDate
        self.CategoryImage = CategoryImage
        self.SubCategoryArray = SubCategoryArray
    



class SubCategoryArray

    var SubCategoryName: String?
    var SubCategoryRefID: String?
    var SubCategoryID: String?
    var SubCategoryDate: String?
    var TextArray : [TextArray]?
    init(SubCategoryName: String?, SubCategoryRefID: String?, SubCategoryID: String?, SubCategoryDate: String?, TextArray: [TextArray]?) 
        self.SubCategoryName = SubCategoryName
        self.SubCategoryRefID = SubCategoryRefID
        self.SubCategoryID = SubCategoryID
        self.SubCategoryDate = SubCategoryDate
        self.TextArray = TextArray
    



class TextArray

    var TextID: String?
    var Text: String?

    init (TextID:String? , Text: String? )
    
        self.TextID = TextID
        self.Text = Text
    

我将它存储为

if let json = try? JSON(result)
var menus = [Menu]()                    
for (_, content) in json["data"] 
let menu = Menu(CategoryName: (content["CategoryName"].string),
 CategoryID: content["CategoryID"].string,
 CategoryDate: content["CategoryDate"].string,
 CategoryImage: content["CategoryImage"],
 SubCategoryArray: content["SubCategoryArray"].string)
 menus.append(menu)
 

唯一的问题是如何为SubCategory 类和TextArray 类执行此操作。

【问题讨论】:

为什么不用 ObjectMapper 而不是 swiftyjson 呢? 【参考方案1】:

首先,我建议将变量名小写。

另外,我会将TextArray 类重命名为Text,将SubCategoryArray 类重命名为SubCategory,因为它们不是数组,而且名称可能会产生很大的误导性。

最后,让我们将subCategoryArraytextArray 初始化为SubCategoryText 的空数组,而不是可选的。这样以后无论什么时候使用,都不需要运行nil检查,只要检查isEmpty就行了。

您需要做的只是迭代传入的对象,并创建您的数组。请看下面的代码。

class Menu 
    var categoryName: String?
    var categoryID: String?
    var categoryDate: String?
    var categoryImage: String?
    var subCategoryArray = [SubCategory]()

    init(categoryName: String?, categoryID: String?, categoryDate: String?, categoryImage: String?, subCategoryArray: [Any]?) 
        self.categoryName = categoryName
        self.categoryID = categoryID
        self.categoryDate = categoryDate
        self.categoryImage = categoryImage

        // lets check if SubCategoryArray is not nil
        if let subCategoryArray = subCategoryArray as? [[String: AnyObject]] 
            // lets iterate on the raw data
            subCategoryArray.forEach( (subCategoryCandidate) in
                // Create category
                let subcategory = SubCategory(subCategoryName: subCategoryCandidate["SubCategoryName"] as? String, 
                    subCategoryRefID: subCategoryCandidate["SubCategoryRefID"] as? String, 
                    subCategoryID: subCategoryCandidate["SubCategoryID"] as? String,
                    subCategoryDate: subCategoryCandidate["SubCategoryDate"] as? String, 
                    textArray: subCategoryCandidate["TextArray"] as? [[String: AnyObject]])
                // Append to our array
                self.subCategoryArray.append(subcategory)
            )
        
    


// lets rename this class only to SubCategory, because this is not an array at all
class SubCategory 
    var subCategoryName: String?
    var subCategoryRefID: String?
    var subCategoryID: String?
    var subCategoryDate: String?
    var textArray = [Text]()
    init(subCategoryName: String?, subCategoryRefID: String?, subCategoryID: String?, subCategoryDate: String?, textArray: [[String: AnyObject]]?) 
        self.subCategoryName = subCategoryName
        self.subCategoryRefID = subCategoryRefID
        self.subCategoryID = subCategoryID
        self.subCategoryDate = subCategoryDate

        if let textArray = textArray 
            textArray.forEach( (textArrayCandidate) in
                let text = Text(textID: textArrayCandidate["TextID"] as? String, text: textArrayCandidate["Text"] as? String)
                self.textArray.append(text)
            )
        
    


// Rename this to Text, because this is also not an array
class Text 
    var textID: String?
    var text: String?

    init(textID:String? , text: String? ) 
        self.textID = textID
        self.text = text
    

用法

let url = URL(string: "YOUR-URL")
let request = URLRequest(url: url!)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

let task = session.dataTask(with: request, completionHandler: (data, response, error) in
    if let data = data, let json = try? JSON(data) 

        var menus = [Menu]()                    
        for (_, content) in json["data"] 
            let menu = Menu(categoryName: (content["CategoryName"].string),
                            categoryID: content["CategoryID"].string,
                            categoryDate: content["CategoryDate"].string,
                            categoryImage: content["CategoryImage"].string,
                            subCategoryArray: content["SubCategoryArray"].arrayObject)
            menus.append(menu)
        

        print(menus) // prints 6 items for me
    
);
task.resume()        

【讨论】:

可能通过编写单元测试?或者你是什么意思? 抱歉这个荒谬的问题好吧,我使用中断绑定,这部分代码跳过 if let subCategoryArray = subCategoryArray // 让我们迭代原始数据 subCategoryArray.forEach( (subCategoryCandidate) in and存储的值为 nil subCategoryArray: content["SubCategoryArray"] as? [[字符串:AnyObject]]) 。我在这里收到一条警告,从 JSON 转换为不相关的类型 [[String:AnyObject]] 总是失败 我一会儿看看 它必须与您使用 SwiftyJSON 有关。你需要在那里找到一系列字典。它应该类似于 content["SubCategoryArray"].array。我目前正在查看 SwiftyJSON 文档,将返回确切的解决方案。

以上是关于如何将嵌套数组添加到我的模型类的主要内容,如果未能解决你的问题,请参考以下文章

如果我有 3 个嵌套数据,如何将 JSON 数据添加到我的数据表中?

如何将新模型添加到嵌套模型导轨

如何在mongodb的嵌套数组中添加数据

将用户与 Rails 中的嵌套模型相关联

如何在mongodb的数组对象的嵌套数组中添加元素

如何使用 Node.js 和 Mongoose 将对象添加到嵌套数组