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

出现此问题是因为您在设置 nametitle 变量之前创建警报。尝试将 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")
}