Swift 带有 Firebase 数据字符串的 Firebase UIAlertView
Swift Firebase UIAlertView with Firebase data strings
我一直在努力寻找解决方案,但没有成功:/我想调用我的 firebase 数据字符串并将它们用作 UIAlertView 中的 "title" 和 "message"。我将此 UIAlertView 用作地理围栏消息。如果我只是将 UIAlertView 设置为我在消息中输入的基本视图,地理围栏就可以工作,但我需要它来调用他们为其他用户编写的消息以供阅读。到目前为止,此设置只会弹出 "Ok" 按钮,进入某个区域后不会弹出任何其他内容。
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
showAlert(withTitle: name, message: message)
//showAlert(withTitle: "Enter \(region.identifier)", message: "Geofence Message")
print(state)
print("region :\(region.identifier)")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
showAlert()
//showAlert(withTitle: "Enter \(region.identifier)", message: "Geofence Message")
print("DID ENTER REGION")
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
//showAlert(withTitle: "Exit \(region.identifier)", message: "Message Exit")
//TODO: stop local sequence
print("DID EXIT REGION")
}
func showAlert(withTitle title: String?, message: String?) {
FIRDatabase.database().reference().child("Businesses").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
})
}
更多信息
// Populate Map With Firebase Businesses
func loadPlaces(){
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
FIRDatabase.database().reference().child("Businesses").observe(.value, with: { snapshot in
self.locationData = snapshot.value as? NSDictionary
if let data = self.locationData{
for (key,obj) in data{
let value = obj as? NSDictionary
let locationValue = value as! [String: Any]
let lat = Double(locationValue["businessLatitude"] as! String)
let long = Double(locationValue["businessLongitude"] as! String)
let businessTitle = String(locationValue["businessName"] as! String)
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let radius = CLLocationDistance(500.0)
let geoRegion = CLCircularRegion(center: center, radius: radius, identifier: businessTitle!)
self.geofences.append(geoRegion)
self.locationManager.startMonitoring(for: geoRegion)
let overlay = MKCircle(center: center, radius: radius)
self.mapView.add(overlay)
geoRegion.notifyOnEntry = true
geoRegion.notifyOnExit = true
let annotation = MKPointAnnotation()
annotation.coordinate = geoRegion.center
annotation.title = businessTitle
self.mapView.addAnnotation(annotation)
self.nameKeyDict[(value?.value(forKey: "businessName") as? String)!] = key as? String
}
}
})
} else {
print("No Bueno")
}
}
Firebase 数据结构
FireBase Data Structure
出现此问题是因为您在设置 name
和 title
变量之前创建警报。尝试将 name 和 title 的初始化更改为 main queue。并使用具有完成块的 Firebase observeSingleEvent
并在完成内部创建警报以确保从 firebase 获取的值已完成。
这是因为异步调用了观察者事件,并且在获取值之前调用了您的警报控制器。
使用一个函数通过完成处理程序检索您的 firebase 值,如下所示:
func retrieveGeofenceMessage(with region: CLRegion, completionHandler: @escaping (Bool) -> Void){
FIRDatabase.database().reference().child("Businesses").child(region.identifier).observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
completionHandler(true)
})
}
然后从你调用你编写的函数的地方:
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
retrieveGeofenceMessage(with: region){
if [=11=] {
// Create Alert controller here
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
}
print("DID ENTER REGION")
}
观察事件执行后,您现在会收到通知并确保您不会使用任何尚未设置的变量。
尝试使用这种方式希望它会有所帮助
FIRDatabase.database().reference().child("Businesses").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
self.alertPopup(name: self.name, message: self.message)
}
})
}
func alertPopup (name: NSString, message: NSString){
let alert = UIAlertController(title: name as String, message: message as String, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
这里是任何有兴趣的人的答案,对 firebase 的非常简单的查询检查。而不是其他人在这里张贴的所有疯狂。请记住将 "region.identifier" 设置为与 "queryOrderded" 相同的值,以便 Firebase 提取正确的 "users" 数据。然后在 firebase 调用中使用“.childAdded”而不是“.value”来检查 Firebase 数据库中的 "users" 而不是它们的值。
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
FIRDatabase.database().reference().child("Businesses").queryOrdered(byChild: "businessName").queryEqual(toValue: region.identifier).observe(.childAdded, with: { snapshot in
if snapshot.exists() {
if let dictionary = snapshot.value as? [String:Any] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
} else {
print("Snap doesnt exist")
}
})
print("DID ENTER REGION")
}
我一直在努力寻找解决方案,但没有成功:/我想调用我的 firebase 数据字符串并将它们用作 UIAlertView 中的 "title" 和 "message"。我将此 UIAlertView 用作地理围栏消息。如果我只是将 UIAlertView 设置为我在消息中输入的基本视图,地理围栏就可以工作,但我需要它来调用他们为其他用户编写的消息以供阅读。到目前为止,此设置只会弹出 "Ok" 按钮,进入某个区域后不会弹出任何其他内容。
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
showAlert(withTitle: name, message: message)
//showAlert(withTitle: "Enter \(region.identifier)", message: "Geofence Message")
print(state)
print("region :\(region.identifier)")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
showAlert()
//showAlert(withTitle: "Enter \(region.identifier)", message: "Geofence Message")
print("DID ENTER REGION")
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
//showAlert(withTitle: "Exit \(region.identifier)", message: "Message Exit")
//TODO: stop local sequence
print("DID EXIT REGION")
}
func showAlert(withTitle title: String?, message: String?) {
FIRDatabase.database().reference().child("Businesses").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
})
}
更多信息
// Populate Map With Firebase Businesses
func loadPlaces(){
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
FIRDatabase.database().reference().child("Businesses").observe(.value, with: { snapshot in
self.locationData = snapshot.value as? NSDictionary
if let data = self.locationData{
for (key,obj) in data{
let value = obj as? NSDictionary
let locationValue = value as! [String: Any]
let lat = Double(locationValue["businessLatitude"] as! String)
let long = Double(locationValue["businessLongitude"] as! String)
let businessTitle = String(locationValue["businessName"] as! String)
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let radius = CLLocationDistance(500.0)
let geoRegion = CLCircularRegion(center: center, radius: radius, identifier: businessTitle!)
self.geofences.append(geoRegion)
self.locationManager.startMonitoring(for: geoRegion)
let overlay = MKCircle(center: center, radius: radius)
self.mapView.add(overlay)
geoRegion.notifyOnEntry = true
geoRegion.notifyOnExit = true
let annotation = MKPointAnnotation()
annotation.coordinate = geoRegion.center
annotation.title = businessTitle
self.mapView.addAnnotation(annotation)
self.nameKeyDict[(value?.value(forKey: "businessName") as? String)!] = key as? String
}
}
})
} else {
print("No Bueno")
}
}
Firebase 数据结构
FireBase Data Structure
出现此问题是因为您在设置 name
和 title
变量之前创建警报。尝试将 name 和 title 的初始化更改为 main queue。并使用具有完成块的 Firebase observeSingleEvent
并在完成内部创建警报以确保从 firebase 获取的值已完成。
这是因为异步调用了观察者事件,并且在获取值之前调用了您的警报控制器。
使用一个函数通过完成处理程序检索您的 firebase 值,如下所示:
func retrieveGeofenceMessage(with region: CLRegion, completionHandler: @escaping (Bool) -> Void){
FIRDatabase.database().reference().child("Businesses").child(region.identifier).observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
completionHandler(true)
})
}
然后从你调用你编写的函数的地方:
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
retrieveGeofenceMessage(with: region){
if [=11=] {
// Create Alert controller here
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
}
print("DID ENTER REGION")
}
观察事件执行后,您现在会收到通知并确保您不会使用任何尚未设置的变量。
尝试使用这种方式希望它会有所帮助
FIRDatabase.database().reference().child("Businesses").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
self.alertPopup(name: self.name, message: self.message)
}
})
}
func alertPopup (name: NSString, message: NSString){
let alert = UIAlertController(title: name as String, message: message as String, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
这里是任何有兴趣的人的答案,对 firebase 的非常简单的查询检查。而不是其他人在这里张贴的所有疯狂。请记住将 "region.identifier" 设置为与 "queryOrderded" 相同的值,以便 Firebase 提取正确的 "users" 数据。然后在 firebase 调用中使用“.childAdded”而不是“.value”来检查 Firebase 数据库中的 "users" 而不是它们的值。
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
FIRDatabase.database().reference().child("Businesses").queryOrdered(byChild: "businessName").queryEqual(toValue: region.identifier).observe(.childAdded, with: { snapshot in
if snapshot.exists() {
if let dictionary = snapshot.value as? [String:Any] {
self.name = dictionary["businessName"] as? String
self.message = dictionary["geofenceMessage"] as? String
}
let alert = UIAlertController(title: self.name, message: self.message, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
} else {
print("Snap doesnt exist")
}
})
print("DID ENTER REGION")
}