繁体   English   中英

如何将解析后的数据存储在数组中?

[英]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 letif 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM