Swift - 如何使用 'shouldChangeTextInRange' 和 Firebase 进行实时搜索?
Swift - How Can I use 'shouldChangeTextInRange' with Firebase for real time searching?
我想知道如何使用 shouldChangeTextInRange 创建 Firebase 匹配正则表达式查询 和 列出当前结果。
我之前在 Parse 中做过,用于在 Parse Cloud 中搜索用户名或用户全名。如果有人阐明了我在 Firebase 中的路径,那就太好了。
// search updated
func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
// find by username
let usernameQuery = PFQuery(className: "_User")
usernameQuery.whereKey("username", matchesRegex: "(?i)" + searchBar.text!)
usernameQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// if no objects are found according to entered text in username column, find by fullname
if objects!.isEmpty {
let fullnameQuery = PFUser.query()
fullnameQuery?.whereKey("fullname", matchesRegex: "(?i)" + self.searchBar.text!)
fullnameQuery?.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// clean up
self.usernameArray.removeAll(keepCapacity: false)
self.avaArray.removeAll(keepCapacity: false)
// found related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.avaArray.append(object.objectForKey("avatar") as! PFFile)
}
// reload
self.tableView.reloadData()
}
})
}
}
// clean up
self.usernameArray.removeAll(keepCapacity: false)
self.avaArray.removeAll(keepCapacity: false)
// found related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.avaArray.append(object.objectForKey("avatar") as! PFFile)
}
// reload
self.tableView.reloadData()
}
return true
}
Update 1:
我不能使用相同的父名称,snap.value 没有给我回应,甚至没有编译。所以我尝试像这样做两个单独的父节点:firebase screen shot link
我收到 indexOn 安全警告 每个字母笔画 first_name 子节点 在 xcode 控制台上:
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/T" at /people_spell to your security rules for better performance
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/Te" at /people_spell to your security rules for better performance
... much more times
我已经尝试了这些安全规则它并没有解决这些问题。它不包含每个子节点。我怎样才能提供这个?
"people_spell": {
".read": "auth !== null",
".write": "auth !== null",
".indexOn": "first_name"
},
"people": {
".read": "auth !== null",
".write": "auth !== null",
".indexOn": "first_name"
}
我正在使用这些代码行:
let peopleSpellRef = Firebase(url: "https://sampleproject.firebaseio.com/people_spell")
let peopleRef = Firebase(url: "https://sampleproject.firebaseio.com/people")
func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
self.usernameArray.removeAll(keepCapacity: false)
peopleSpellRef.queryOrderedByChild("first_name/\(searchBar.text!)").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? FDataSnapshot {
peopleRef.childByAppendingPath("\(rest.key)").observeEventType(.Value, withBlock: { snapshot in
self.usernameArray.removeAll(keepCapacity: false)
let str: String = (snapshot.value.objectForKey("first_name")) as! (String)
print(str)
self.usernameArray.append(str)
self.userkeyArray.append(snapshot.key)
self.tableView.reloadData()
})
}
self.usernameArray.removeAll(keepCapacity: false)
self.tableView.reloadData()
})
return true
}
这不是 Firebase 的工作方式,您不能在 Firebase 中直接对子字符串执行 'real time search'。但是,您可以格式化要搜索的 Firebase 数据,还有一些其他方法也可以实现这一目标。
一个很简单:将您的数据从 Firebase 加载到数组中,然后通过数组进行 NSPredicate 搜索(或其他方法)。
另一个是查询完整字符串很容易;只要文本被分解成您要搜索的块:
people
person_0
first_name: "Ted"
last_name: "Stryker"
position: "sitting down and facing front"
person_1
first_name: "Teddy"
可以在first_name中搜索'Ted',在last_name中搜索'Stryker',但不能在position中搜索'front'。
现在解决方法并记住磁盘 space 很便宜。
可以创建一个节点,让您可以通过多种方式搜索内容
people
person_0
first_name //First name is Ted from above
T: true
Te: true
Ted: true
ed: true
d: true
e: true
person_1
first_name //First name is Teddy from above
T: true
Te: true
Ted: true
etc
通过这种结构,我们可以找到所有以 Ted 开头的名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
print(child.value)
}
})
可以执行其他搜索;搜索所有包含 e 或 Te 等的名字
如果这纯粹是您要搜索以在文本字段中执行自动填充的情况(例如),则逐个按键 ping firebase 效果不佳。
将数据从 Firebase 加载到数组或字典(或其他)中可能是您的最佳解决方案。
我想知道如何使用 shouldChangeTextInRange 创建 Firebase 匹配正则表达式查询 和 列出当前结果。
我之前在 Parse 中做过,用于在 Parse Cloud 中搜索用户名或用户全名。如果有人阐明了我在 Firebase 中的路径,那就太好了。
// search updated
func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
// find by username
let usernameQuery = PFQuery(className: "_User")
usernameQuery.whereKey("username", matchesRegex: "(?i)" + searchBar.text!)
usernameQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// if no objects are found according to entered text in username column, find by fullname
if objects!.isEmpty {
let fullnameQuery = PFUser.query()
fullnameQuery?.whereKey("fullname", matchesRegex: "(?i)" + self.searchBar.text!)
fullnameQuery?.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// clean up
self.usernameArray.removeAll(keepCapacity: false)
self.avaArray.removeAll(keepCapacity: false)
// found related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.avaArray.append(object.objectForKey("avatar") as! PFFile)
}
// reload
self.tableView.reloadData()
}
})
}
}
// clean up
self.usernameArray.removeAll(keepCapacity: false)
self.avaArray.removeAll(keepCapacity: false)
// found related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.avaArray.append(object.objectForKey("avatar") as! PFFile)
}
// reload
self.tableView.reloadData()
}
return true
}
Update 1:
我不能使用相同的父名称,snap.value 没有给我回应,甚至没有编译。所以我尝试像这样做两个单独的父节点:firebase screen shot link
我收到 indexOn 安全警告 每个字母笔画 first_name 子节点 在 xcode 控制台上:
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/T" at /people_spell to your security rules for better performance
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/Te" at /people_spell to your security rules for better performance
... much more times
我已经尝试了这些安全规则它并没有解决这些问题。它不包含每个子节点。我怎样才能提供这个?
"people_spell": {
".read": "auth !== null",
".write": "auth !== null",
".indexOn": "first_name"
},
"people": {
".read": "auth !== null",
".write": "auth !== null",
".indexOn": "first_name"
}
我正在使用这些代码行:
let peopleSpellRef = Firebase(url: "https://sampleproject.firebaseio.com/people_spell")
let peopleRef = Firebase(url: "https://sampleproject.firebaseio.com/people")
func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
self.usernameArray.removeAll(keepCapacity: false)
peopleSpellRef.queryOrderedByChild("first_name/\(searchBar.text!)").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? FDataSnapshot {
peopleRef.childByAppendingPath("\(rest.key)").observeEventType(.Value, withBlock: { snapshot in
self.usernameArray.removeAll(keepCapacity: false)
let str: String = (snapshot.value.objectForKey("first_name")) as! (String)
print(str)
self.usernameArray.append(str)
self.userkeyArray.append(snapshot.key)
self.tableView.reloadData()
})
}
self.usernameArray.removeAll(keepCapacity: false)
self.tableView.reloadData()
})
return true
}
这不是 Firebase 的工作方式,您不能在 Firebase 中直接对子字符串执行 'real time search'。但是,您可以格式化要搜索的 Firebase 数据,还有一些其他方法也可以实现这一目标。
一个很简单:将您的数据从 Firebase 加载到数组中,然后通过数组进行 NSPredicate 搜索(或其他方法)。
另一个是查询完整字符串很容易;只要文本被分解成您要搜索的块:
people
person_0
first_name: "Ted"
last_name: "Stryker"
position: "sitting down and facing front"
person_1
first_name: "Teddy"
可以在first_name中搜索'Ted',在last_name中搜索'Stryker',但不能在position中搜索'front'。
现在解决方法并记住磁盘 space 很便宜。
可以创建一个节点,让您可以通过多种方式搜索内容
people
person_0
first_name //First name is Ted from above
T: true
Te: true
Ted: true
ed: true
d: true
e: true
person_1
first_name //First name is Teddy from above
T: true
Te: true
Ted: true
etc
通过这种结构,我们可以找到所有以 Ted 开头的名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
print(child.value)
}
})
可以执行其他搜索;搜索所有包含 e 或 Te 等的名字
如果这纯粹是您要搜索以在文本字段中执行自动填充的情况(例如),则逐个按键 ping firebase 效果不佳。
将数据从 Firebase 加载到数组或字典(或其他)中可能是您的最佳解决方案。