簡體   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