是否有从 firebase 实时数据库中获取 n 个元素的功能?
Posted
技术标签:
【中文标题】是否有从 firebase 实时数据库中获取 n 个元素的功能?【英文标题】:Is there a function for get n elements from firebase realtime database? 【发布时间】:2018-12-21 14:46:48 【问题描述】:我的代码包含 3 个 swift 文件,用于创建动态原型 UITableViewController
。
1) Rent_house_Controller.swift
2) Rent_house_Cell.swift
3) Rent_house_Detail.swift
首先我将UITableViewCell
的对象连接到专用的swift文件:
@IBOutlet weak var rentImage: UIImageView!
@IBOutlet weak var rentLabel: UILabel!
然后我定义了我的UITableViewController
:
import UIKit
import FirebaseDatabase
class Case_in_affitto: UITableViewController,
UISearchResultsUpdating, UISearchBarDelegate
var rentImages = [String]()
var rentNames = [String]()
var webAddresses = [String]()
var searching = false
var matches = [Int]()
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad()
super.viewDidLoad()
initialize()
func initialize()
rentNames = ["Red Street",
"Green Street",
"Blue steet",
"Yellow Street",
"Colour Square"]
webAddresses = ["https://website.com/rents/Red-Street",
"https://website.com/rents/Green-Street",
"https://website.com/rents/Blue-Street",
"https://website.com/rents/Yellow-Street",
"https://website.com/rents/Colour-Square"]
rentImages = ["Red-Street.jpg",
"Green-Street.jpg",
"Blue-Street.jpg",
"Yellow-Street.jpg",
"Colour-Square.jpg"]
tableView.estimatedRowHeight = 50
navigationController?.navigationBar.prefersLargeTitles = true
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Cerca immobile"
navigationItem.searchController = searchController
definesPresentationContext = true
let attributes = [
NSAttributedString.Key.foregroundColor : UIColor.white,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 17)
]
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Annulla"
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
// MARK: Search Controller
func updateSearchResults(for searchController: UISearchController)
if let searchText = searchController.searchBar.text,
!searchText.isEmpty
matches.removeAll()
for index in 0..<rentNames.count
if rentNames[index].lowercased().contains(
searchText.lowercased())
matches.append(index)
searching = true
else
searching = false
tableView.reloadData()
func searchBarCancelButtonClicked(_ searchBar: UISearchBar)
searching = false
tableView.reloadData()
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return searching ? matches.count : rentNames.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell
let row = indexPath.row
cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
cell.rentLabel.text = searching ? rentNames[matches[row]] : rentNames[row]
let imageName = searching ? rentImages[matches[row]] : rentImages[row]
cell.rentImage.image = UIImage(named: imageName)
return cell
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "ShowrentDetails"
let detailViewController = segue.destination
as! Case_in_Affitto_Detail
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
detailViewController.webSite =
searching ? webAddresses[matches[row]] : webAddresses[row]
//Set cells height
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
switch indexPath.row
case 0,1,2,3,4:
return 100
default:
return 40
在这种情况下,我有一个经典的UITableViewController
,它显示了我在项目中实现的值,但我需要一些不同的东西。
我想根据我在数据库中的节点数量来制作 n 个单元格。
例如:
"Sales":"",
"Rents":[
"Address":"Green_Street",
"Rooms":"2",
"Price":"70000"
,
"Address":"Red_Street",
"Rooms":"2",
"Price":"70000"
,
"Address":"Blue_Street",
"vani":"2",
"Price":"70000"
,
"Address":"Yellow_Street",
"Rooms":"2",
"Price":"70000"
,
"Address":"Colour_Square",
"Rooms":"4",
"Price":"140000"
]
换句话说,第一个问题是有一天,房子的数量会增加或减少,所以我需要制作一个函数来自动根据我的数据库的节点数填充表格。?
编辑:
我做了一些东西。
我创建了一个新的UIViewController
,它从数据库中调用数据,然后我想通过UserDefaults.standard
传递所有这些数据
图像是由数据库检索的 URL 提供的,所以我还添加了键“imageURL”。
加载.swift:
if codesArray.contains("0")
let userRef = rootRef.child("Rents").child("0")
userRef.observeSingleEvent(of: .value, with: snapshot in
let userDict = snapshot.value as! [String: Any]
let rentAddress = userDict["Address"] as! String
self.address = rentAddress
let rentnumberOfRooms = userDict["numberOfRooms"] as! String
self.numberOfRooms = rentnumberOfRooms
let rentPrice = userDict["Price"] as! String
self.price = rentPrice
let rentimageURL = userDict["imageURL"] as! String
self.imageURL = rentimageURL
//save data on UserDefaults
self.savedata()
//loading finished
self.loading.stopAnimating()
self.performSegue(withIdentifier: "loadingfinish", sender: self)
)
else
self.loading.stopAnimating()
let alert = UIAlertController(title: "Errore", message: "Caricamento annunci non riuscito", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
如何更改此条件以加载节点“Rent”的每个子嵌套?
(请记住,我们不知道孩子有多少租金)
编辑 2:
我正在尽我所能找到这个解决方案。
我想在while cicle上使用nextObject
参数来检查数据库中是否还有其他对象要存储在var address = [String]()
中
//setting firebase database
while (snapshotChildren.nextObject() as? DataSnapshot) != nil
let string_child = snapshotChildren.nextObject() as? String
let userRef = rootRef.child("Rents").child(string_child!)
userRef.observeSingleEvent(of: .value, with: snapshot in
let userDict = snapshot.value as! [String: Any]
self.address.append(userRef.value(forKey: "Address") as! String)
let rentnumberOfRooms = userDict["numberOfRooms"] as! NSMutableArray
self.numberOfRooms = rentnumberOfRooms
let rentPrice = userDict["Price"] as! NSMutableArray
self.price = rentPrice
let rentimageURL = userDict["imageURL"] as! NSMutableArray
self.imageURL = rentimageURL
//avvio salvataggio dati del volontario
func prepare(for segue: UIStoryboardSegue, sender: Any?)
let vc = segue.destination as! Case_in_affitto
var i = 0
while i==5
//this will pass the value on the address array in the Case_in_affitto.swift file
vc.address.append(self.address[i])
i += 1
)
//loading complete
self.loading.stopAnimating()
self.performSegue(withIdentifier: "loadingfinish", sender: self)
很遗憾,这是不正确的
【问题讨论】:
【参考方案1】:Il codice è abbastanza orribile ?(代码很可怕)
不要使用多个数组作为数据源。您已经在搜索功能中遇到了麻烦。
使用带有所有您需要的参数的自定义结构,图像由它在包中的名称表示
struct Rent
let address : String
let numberOfRooms : Int
let price : String
let image : String
初始化器
init(address : String, numberOfRooms : Int, price : String, image : String)
免费提供。
声明一个数据源数组并从数据库中填充
var rents = [Rent]()
用相同的类型声明matches
var matches = [Rent]()
并使用此优化代码过滤对象,diacriticInsensitive
对于意大利语文本非常有用。
func updateSearchResults(for searchController: UISearchController)
if let searchText = searchController.searchBar.text,
!searchText.isEmpty
matches = rents.filter $0.name.range(of: searchText, options: [.caseInsensitive, .diacriticInsensitive]) != nil
searching = true
else
matches.removeAll()
searching = false
tableView.reloadData()
对应的表视图委托方法是
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return searching ? matches.count : rents.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell
let object = searching ? matches[indexPath.row] : rents[indexPath.row]
cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
cell.rentLabel.text = object.name
cell.rentImage.image = UIImage(named: object.image)
return cell
如果图像不应该位于捆绑包中,请将 URL 保存在数据库中,并将物理图像保存在 Documents
文件夹中。
在这种情况下声明
let imageURL : URL
在结构中并分配图像
cell.rentImage.image = UIImage(contentsOfFile: object.imageURL.path)
【讨论】:
谢谢,非常好!但是调试器说“初始化器只能在一个类型中声明” 我明白我必须将所有这些代码都放在控制器中。这里所有的错误:在函数初始化中:init(地址:字符串...)行:初始化程序只能在类型类 Case_in_affitto 行中声明:类型'Case_in_affitto'不符合协议'UISearchResultsUpdating'类'Case_in_affitto'没有初始化匹配=rents.filter 行:'Rent' 类型的值没有成员'name' cell.rentLabel.text = obkect.name 行:'Rent' 类型的值没有成员'name' cell.rentImage.image = UIImage 行:'Rent' 类型的值在函数准备搜索中没有成员 'imageURL' 吗? webAddresses[matches[row]] : webAddresses[row] 行:无法使用“Rent”类型的索引为“[String]”类型的值下标 在类外声明结构。var rents...
替换了三个字符串数组。在initialize
中删除初始化行并用rents = [Rent(name: "Red Street", numberOfRooms: 2, price: "70000", image: "Red-Street.jpg"), Rent(name: "Blue Street", ....), Rent(name: "Green Street", ....)]
填充rents
。如果图像不在应用程序包中,imageURL
是一种替代方法。
是的,现在可以使用了。但 Firebase 仍未配置。这样,单元格值仍然由 swift 文件检索。过去我使用观察者来查看已知数量的行,但这次我们不知道数据库中有多少数据。以上是关于是否有从 firebase 实时数据库中获取 n 个元素的功能?的主要内容,如果未能解决你的问题,请参考以下文章
无法从 firebase 回收器视图中的 firebase 实时数据库中获取嵌套数据