动态生成UITableView单元和头部

时间:2016-01-29 01:26:54

标签: json swift uitableview alamofire swifty-json

项目文件:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53k

(明智地看这些看项目的结构)

问题:

好的,所以我正在关注tutorial,创建一个带标题的UITableView,然后是单元格内容。

代码运行良好,现在我希望扩展到该教程之外,并使用alamofire和SwiftyJSON动态加载该内容。

在本教程中,使用的代码如下:

func getSectionsFromData() -> [Sections] {

    var sectionsArray = [Sections]()

    let animals = Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"])


    sectionsArray.append(animals)

    return sectionsArray


}

我试图做的是:

Alamofire.request(.GET, url).validate().responseJSON { response in
        switch response.result {
        case .Success:
            if let value = response.result.value {
                let json = JSON(value)

                for (_, subJson) in json {
                    for (year, content) in subJson {
                        let title = year
                        let objects = content

                        sectionsArray.append(Sections(title: title, objects: objects))

                    }

                }
            }
        case .Failure(let error):
            print(error)
        }
    }

如果我打印出他们在控制台中显示的结果 - 所以我知道JSON的获取和循环工作。然后我加入了

let title = year
let objects = content

sectionsArray.append(Sections(title: title, objects: objects))

但是就这一行:

  

sectionsArray.append(Sections(title:title,objects:objects))

我收到此错误:

  

无法将'JSON'类型的值转换为预期的参数类型'[String]'

这是我正在使用的JSON:

 {"posts": [
 {
    "Category1": [
        "Post1cat1"
    ],
    "Category2": [
        "Post1cat2",
        "Post2cat2"
    ]
 }
 ]}

有人能帮助我吗? 我可能会走错方向我想循环遍历JSON并将类别显示为表格的单元格和帖子。

编辑:2016年1月29日

所以,我把循环改为:

for (_, subJson) in json {
                for (index, data) in subJson {
                    for (title, objects) in data {
                        sectionsArray.append(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!}))


                    }

                }

            }

仍然没有运气。当我添加一些打印件(在:sectionsArray.append下)来测试是否有数据:

print("--")
print(title)
print(objects.self.arrayValue.map { $0.string!})
print(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!}))

我在控制台中得到了这个结果:

  

-

     

组别

     

[ “Post1cat1”]

     

章节(标题:“Category1”,项目:[“Post1cat1”])

     

-

     

类别2

     

[“Post1cat2”,“Post2cat2”]

     

章节(标题:“Category2”,项目:[“Post1cat2”,“Post2cat2”])

这表明信息存在,但是当我运行应用程序时,仍然没有结果形式他JSON只是最初定义的部分和上面的单元格。

3 个答案:

答案 0 :(得分:3)

在第二个解析方法(编辑后)中,你在最后一个循环中迭代数组,所以你可以在那里创建数组并分别添加每个元素,如例:

for (title, data) in subJson {
    var elements: [String] = []

    for (_, object) in data {
        if let stringELement = object.rawString() {
            elements.append(stringELement)
        }
    }

    sectionsArray.append(Sections(title: title, objects: elements))
}

或者如果您愿意,可以使用JSON对象中的casted raw数组,如下例所示:

for (_, subJson) in json["posts"] {
    for (title, data) in subJson {
        let optionalCastedObjects = data.arrayObject as? [String]
        let unwrappedObjects = optionalCastedObjects ?? []
        let section = Sections(title: title, objects: unwrappedObjects)

        sectionsArray.append(section)                        
    }
}

那应该修复提到的编译问题。

但最后请记住,您在同步GET request方法中使用了异步回调(在getSectionsFromData中)。在回调(clojure)的值附加新数据之前,您总是会返回数组。这将导致您永远不会显示您以这种方式获取的数据。

<强>更新

为此,您应该重构getSectionsFromData方法,如下所示。

func getSectionsFromData(completion: ([Sections]) -> ()) {
    var sectionsArray = [Sections]()

    Alamofire.request(.GET, url).validate().responseJSON { response in
        switch response.result {
        case .Success:
            if let value = response.result.value {
                let json = JSON(value)

                for (_, subJson) in json["posts"] {
                    for (title, data) in subJson {
                        let optionalCastedObjects = data.arrayObject as? [String]
                        let unwrappedObjects = optionalCastedObjects ?? []
                        let section = Sections(title: title, objects: unwrappedObjects)

                        sectionsArray.append(section)
                    }
                }

                completion(sectionsArray)
            }
        case .Failure(let error):
            print(error)
        }
    }
}

UITableViewController类中的相关部分。

var sections: [Sections] = []

override func viewDidLoad() {
    super.viewDidLoad()

    SectionsData().getSectionsFromData { [weak self](sections: [Sections]) -> () in
        self?.sections = sections
        self?.tableView.reloadData()
    }
}

答案 1 :(得分:1)

你的第二个循环在数组对象上,因此循环year是索引值,content是该索引的对象。

你需要实现一个额外的循环来解决问题,即:

for (_, subJson) in json {
    for (index, data) in subJson {
        for (title, objects) in data {
            sectionsArray.append(Sections(title: title, objects: objects.arrayValue.map { $0.string!}))

        }

    }

}

答案 2 :(得分:-1)

来自SwiftyJSON文档:

for (key,subJson):(String, JSON) in json {
   //Do something you want
}

这表明subJson的类型为JSON。但是,第一个示例中的Sections构造函数是:

Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"])

在您的第二个示例中,您将其称为:

Sections(title: title, objects: objects)

除非你更改了构造函数,否则它期望objects是一个字符串数组,而不是JSON。这就是为什么你得到一个错误,说Swift无法将JSON转换为String。在您的情况下,objects JSON实际上是一个字符串数组,因此您需要使用以下内容:

Sections(title: title, objects: objects.arrayValue.map { $0.string!})