Nic*_*ner 0 offline ios firebase swift firebase-realtime-database
我正在使用Firebase构建一个Swift应用程序,而且我是两个新手,所以要温柔.目前,当我打开应用程序时,它会再次同步整个数据库,并导致2或3秒滞后,用户盯着空的tableview.我怎样才能加快速度呢?
有什么想法吗?
我的代码:
我的loadContacts函数
func loadContact(snap : FIRDataSnapshot) -> Contact {
let key = snap.key
let contact = (snap.value) as? NSDictionary
let c1 = Contact(
id: (contact?["id"] as? String)!,
firebasekey: key,
first_name: (contact?["First Name"] as? String)!,
middle_name: (contact?["Middle Name"] as? String)!,
last_name: (contact?["Last Name"] as? String)!,
suffix: (contact?["Suffix"] as? String)!,
company: (contact?["Company"] as? String)!,
phone_labe1: (contact?["Phone Label 1"] as? String)!,
phone1: (contact?["Phone 1"] as? String)!,
phone_label2: (contact?["Phone Label 2"] as? String)!,
phone2: (contact?["Phone 2"] as? String)!,
email_label1: (contact?["Email Label 1"] as? String)!,
email1: (contact?["Email 1"] as? String)!,
email_label2: (contact?["Email Label 2"] as? String)!,
email2: (contact?["Email 2"] as? String)!,
social: (contact?["Social Security Number"] as? String)!,
dob: (contact?["Date of Birth"] as? String)!,
street: (contact?["Street"] as? String)!,
city: (contact?["City"] as? String)!,
zip: (contact?["ZIP and Postal Code"] as? String)!,
state: (contact?["State and Province"] as? String)!,
reg_number: (contact?["Reg Num"] as? String)!,
stable_reg_number: (contact?["Stable Reg Num"] as? String)!,
emergency_contact: (contact?["Emergency Contact"] as? String)!,
emergency_phone: (contact?["Emergency Phone"] as? String)!,
drivers_license: (contact?["Driver's License Num"] as? String)!,
insurance_carrier: (contact?["Insurance Carrier"] as? String)!,
details: (contact?["Details"] as? String)!,
insurance_exp: (contact?["Insurance Expiration Date"] as? String)!,
insurance_group: (contact?["Insurance Group Num"] as? String)!,
insurance_member: (contact?["Insurnace Member Num"] as? String)!, // spelled wrong in database
job_title: (contact?["Job Title"] as? String)!,
date_modified: (contact?["Modified"] as? String)!,
keywords: [],
notes: []
)
return c1;
}
Run Code Online (Sandbox Code Playgroud)
并在我的联系表视图中
import UIKit
import Firebase
class ContactTableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
// MARK: Properties
var contactSearchResults : [Contact] = []
// FIRDatabase.database().persistenceEnabled = true
let contactRef = FIRDatabase.database().reference().child("contacts")
override func viewDidLoad() {
contactRef.queryOrdered(byChild: "Last Name").observe(.childAdded) { (snap: FIRDataSnapshot) in
contacts.append(loadContact(snap: snap))
self.tableView.reloadData()
}
contactRef.queryOrdered(byChild: "Last Name").observe(.childChanged) { (snap: FIRDataSnapshot) in
// this code here is wrong, but it doesn't matter for demonstration purposes
contacts.append(loadContact(snap: snap))
self.tableView.reloadData()
}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
Run Code Online (Sandbox Code Playgroud)
我的数据库结构如下
联系人(我的问题区域)中有大约4000条记录,每条记录有33个单独的子项值.
问题中的代码存在许多问题,这些问题会影响性能.
1)孩子最初为每个孩子添加事件火灾,然后为之后添加的任何孩子添加事件火灾.如果您有1000个联系人,这意味着在启动时,您将刷新表视图1000次.最好通过.value加载所有联系人并迭代它们,添加到数组,然后在完成后刷新tableView
2)与#1一起使用,如果您只想按姓氏排序,请按.value观察节点,迭代快照以填充数组然后排序,然后重新加载tableView.这将明显加快.
3)childChanged事件:没有理由按姓氏查询,当孩子改变时,它只通知你那个孩子,如果需要,你可以再次输入代码
4)与观察事件相比,Firebase查询非常"繁重".在这种情况下,你真的不是要特别查询,所以应该被淘汰.只需使用观察事件来加载节点的数据,并在查找该数据的子集时使用查询.
*请注意,这很大程度上取决于您拥有多少联系人.对于几千个这些建议工作正常.
因此,有一个非常酷的设计模式,使初始数据集的填充真正干净.我认为其中一个Firebasers将其作为示例应用程序的一部分编写.
我们首先定义一个名为initialLoad的类级变量,并将其设置为true.然后我们使用childAdded观察加载所有联系人并填充我们的tableView dataSource数组.
var initialLoad = true
contactsRef.observeEventType(.ChildAdded, withBlock: { snapshot in
self.handleChildAdded(withSnap: snapshot)
})
Run Code Online (Sandbox Code Playgroud)
以及处理childAdded事件的函数,并且最初会一次加载每个子项,并监视之后添加的子项.
func handleChildAdded(withSnap: snapshot: FDataSnapshot! ) {
let myContact = Contact()
myContact.initWithSnap(snapshot)
myDataSourceArray.append(myContact)
//upon first load, don't reload the tableView until all children are loaded
if ( self.initialLoad == false ) {
self.contactsTableView.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
现在是棘手的一点
//this .Value event will fire AFTER the child added events to reload the tableView
// the first time and to set subsequent childAdded events to load after each child is
// added in the future
contactsRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
print("inital data loaded so reload tableView!")
self.itemsTableView.reloadData()
self.initialLoad = false
})
Run Code Online (Sandbox Code Playgroud)
10k英尺的视图:
这里的关键是.value事件触发AFTER .childAdded事件,因此我们利用它将所有子添加事件完成后的initialLoad变量设置为false.
上面的代码是Swift 2/3,Firebase 2,但它为您提供了如何进行初始加载的概念.
| 归档时间: |
|
| 查看次数: |
1916 次 |
| 最近记录: |