[英]How to store the parsed data in the array?
I have a database on Firebase.我有一个关于 Firebase 的数据库。 I parse some data that I want to store in the array of structures:
我解析了一些我想存储在结构数组中的数据:
postData.swift 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
}
}
This array will be used for creating a collectionViewCells inside a tableViewCells .该数组将用于在tableViewCells中创建collectionViewCells 。 Inside my ViewController I created a global array
var dataPosts:[postData] = []
where I will store parsed data.在我的 ViewController 中,我创建了一个全局数组
var dataPosts:[postData] = []
我将在其中存储解析的数据。 Here is a function I made:这是我制作的 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
}
Is there any way to store it in the array?有没有办法将它存储在数组中? Or I should use something from OOP (I'm a beginner)?
或者我应该使用 OOP 的东西(我是初学者)? Thanks
谢谢
First of all please name structs with starting uppercase letter and variables with starting lowercase letter.首先,请以大写字母开头的结构和以小写字母开头的变量命名。 The
init
method is not needed不需要
init
方法
struct PostData {
let title: String
let subtitle: String
let imgURL: String
let date: String
}
and和
var dataPosts : [PostData] = []
Actually you have only to reload the table view after the loop inside the closure which receives the data asynchronously.实际上,您只需在异步接收数据的闭包内循环之后重新加载表视图。 The temporary array
data
is not needed.不需要临时数组
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()
}
}
And delete并删除
print(dataPosts.count) // prints 0
in viewDidLoad
, it's useless.在
viewDidLoad
中,它没用。
This is only a suggestion, instead of creating a struct
create a NSObject
class instead:这只是一个建议,而不是创建一个
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
}
}
Make sure that the dictionary values such as the title, subtitle, etc. match with your firebase database values names.确保标题、副标题等字典值与您的 firebase 数据库值名称匹配。 I think that yours may be:
我认为你的可能是:
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
}
This way now when reading data you can initialize a PostData object with the dictionary from snapshot and append it to your array (If using it).现在,当读取数据时,您可以使用快照中的字典初始化 PostData object 并将 append 初始化到您的数组(如果使用它)。
EXAMPLE:例子:
// 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)
}
REMEMBER that with your object we are working with optionals values, that means that you may need to use guard let
or if let
statements to make sure this properties are not nil (this may not be the case if this are correctly parsed with your firebase database).请记住,对于您的 object,我们正在使用可选值,这意味着您可能需要使用
guard let
或if let
语句来确保此属性不为零(如果使用 firebase 数据库正确解析,则可能不是这种情况)。
EXAMPLE:例子:
// 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"
This may helps you to write less lines of code and make it simple to understand.这可以帮助您编写更少的代码行并使其易于理解。
COMPLETE EXAMPLE:完整示例:
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()
}
}
This last example is using PostData as a NSObject
class as I showed you on the example above.最后一个示例使用 PostData 作为
NSObject
class,正如我在上面的示例中向您展示的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.