[英]How to store the parsed data in the array?
我有一个关于 Firebase 的数据库。 我解析了一些我想存储在结构数组中的数据:
postData.swift
struct postData {
let Title: String
let Subtitle: String
let imgURL: String
let Date: String
init(Title: String, Subtitle: String, imgURL: String, Date: String) {
self.Title = Title
self.Subtitle = Subtitle
self.imgURL = imgURL
self.Date = Date
}
}
该数组将用于在tableViewCells中创建collectionViewCells 。 在我的 ViewController 中,我创建了一个全局数组var dataPosts:[postData] = []
我将在其中存储解析的数据。 这是我制作的 function:
var dataPosts:[postData] = []
...
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: self.view.bounds, style: .grouped)
tableView.delegate = self
tableView.dataSource = self
...
tableView.register(PostCell.self, forCellReuseIdentifier: PostTableID)
parsePosts()
print(dataPosts.count) // prints 0
}
func parsePosts() {
let databaseRef = Database.database().reference(withPath: "Посты")
var data:[postData]
databaseRef.observeSingleEvent(of: .value) { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let res = snap.value as! [String: Any]
let title = res["Заголовок"] as! String
let subtitle = res["Подзаголовок"] as! String
let img = res["URL"] as! String
let date = res["Дата"] as! String
self.dataPosts.append(postData(Title: title, Subtitle: subtitle, imgURL: img, Date: date))
print(self.dataPosts.count, " - inside cycle") // prints 1
}
}
data = dataPosts
print(data.count, " - inside function") // prints 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataPosts.count
}
有没有办法将它存储在数组中? 或者我应该使用 OOP 的东西(我是初学者)? 谢谢
首先,请以大写字母开头的结构和以小写字母开头的变量命名。 不需要init
方法
struct PostData {
let title: String
let subtitle: String
let imgURL: String
let date: String
}
和
var dataPosts : [PostData] = []
实际上,您只需在异步接收数据的闭包内循环之后重新加载表视图。 不需要临时数组data
。
func parsePosts() {
let databaseRef = Database.database().reference(withPath: "Посты")
databaseRef.observeSingleEvent(of: .value) { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let res = snap.value as! [String: Any]
let title = res["Заголовок"] as! String
let subtitle = res["Подзаголовок"] as! String
let img = res["URL"] as! String
let date = res["Дата"] as! String
self.dataPosts.append(PostData(title: title, subtitle: subtitle, imgURL: img, date: date))
print(self.dataPosts.count, " - inside cycle") // prints 1
}
self.tableView.reloadData()
}
}
并删除
print(dataPosts.count) // prints 0
在viewDidLoad
中,它没用。
这只是一个建议,而不是创建一个struct
,而是创建一个NSObject
class :
import UIKit
class PostData: NSObject {
@objc var title: String?
@objc var subtitle: String?
@objc var imgUrl: String?
@objc var date: String?
init(dictionary: [String: AnyObject]) {
self.title = dictionary["title"] as? String
self.subtitle = dictionary["subtitle"] as? String
self.imgUrl = dictionary["imgUrl"] as? String
self.date = dictionary["date"] as? String
}
}
确保标题、副标题等字典值与您的 firebase 数据库值名称匹配。 我认为你的可能是:
init(dictionary: [String: AnyObject]) {
self.title = dictionary["Заголовок"] as? String
self.subtitle = dictionary["Подзаголовок"] as? String
self.imgUrl = dictionary["URL"] as? String
self.date = dictionary["Дата"] as? String
}
现在,当读取数据时,您可以使用快照中的字典初始化 PostData object 并将 append 初始化到您的数组(如果使用它)。
例子:
// Here you had already observed a single event
if let postDict = snapshot.value as? [String: AnyObject] {
let postData = PostData(dictionary: postDict)
// append to array if needed
self.postsData.append(newElement: postData)
}
请记住,对于您的 object,我们正在使用可选值,这意味着您可能需要使用guard let
或if let
语句来确保此属性不为零(如果使用 firebase 数据库正确解析,则可能不是这种情况)。
例子:
// Let's suppose that you need to access to the "title" property
// This dictionary is a hardcoded dictionary, yours may be downloaded from your database
let dictionary: [String: AnyObject] = [
"title": "a title" as AnyObject,
"subtitle": "a subtitle" as AnyObject,
"imgUrl": "an imgUrl" as AnyObject,
"date": "a date" as AnyObject
]
let postData = PostData(dictionary: dictionary)
// THIS IS THE INCORRECT WAY
let postTitle = postData.title
print(postTitle!) /* The print statement does not require a non-optional value, but may print something like: Optional("a title"), in your case you may want a non-optional value */
// THIS IS THE CORRECT WAY
if let postTitle = postData.title {
print(postTitle) // Prints: "a title"
}
// ALTERNATIVE TO CORRECT WAY
guard let postTitle = postData.title else { return }
print(postTitle) // Prints: "a title"
这可以帮助您编写更少的代码行并使其易于理解。
完整示例:
var postsDataArray = [PostData]()
func parsePosts() {
let databaseRef = Database.database().reference(withPath: "Посты")
databaseRef.observeSingleEvent(of: .value) { (snapshot) in
if let postDict = snapshot.value as? [String: AnyObject] {
let postData = PostData(dictionary: postDict)
self.postsDataArray.append(newElement: postData)
}
self.tableView.reloadData()
}
}
最后一个示例使用 PostData 作为NSObject
class,正如我在上面的示例中向您展示的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.