我使用childByAutoID使用firebase创建了一个唯一的ID。我可以在用于创建它的引用函数中打印此ID,但是当我将值赋给类变量并在控制台中打印它时,它会出现nil。
我正在尝试使用override func prepareForSegue方法将此数据发送到另一个视图控制器。当数据是字符串时它起作用,但当它是包含uniqueIDKey的变量时它不起作用。
以下是代码:
class MainViewController: UIViewController, CLLocationManagerDelegate{
var ref: FIRDatabaseReference!
var refHandle: UInt!
let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 1000
var currentLocation: CLLocation!
var location: CLLocationCoordinate2D!
var latitude: Double!
var longitude: Double!
let geoCoder = CLGeocoder()
var placemark: CLPlacemark?
let date = NSDate()
var currentOrderIDKey = ""
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var userEmailLabel: UILabel!
@IBOutlet weak var pickUpAddress: UITextField!
@IBOutlet weak var deliveryAddress: UITextField!
override func viewDidLoad() {
ref = FIRDatabase.database().reference()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
locationManager.startUpdatingLocation()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
refHandle = ref.observeEventType(FIRDataEventType.Value, withBlock: { (snapshot) in
let dataDict = snapshot.value as! [String: AnyObject]
print((dataDict))
})
let userID: String = FIRAuth.auth()!.currentUser!.uid
ref.child("users").child(userID).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let userEmail = snapshot.value!["email"] as! String
self.userEmailLabel.text = userEmail
})
super.viewDidLoad()
print("\(currentLocation)")
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("didFailWithError \(error)")
if error.code == CLError.LocationUnknown.rawValue {
return
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.last!
latitude = currentLocation.coordinate.latitude
longitude = currentLocation.coordinate.longitude
location = CLLocationCoordinate2DMake(latitude, longitude)
print("didUpdateLocations \(currentLocation.coordinate)")
if currentLocation.timestamp.timeIntervalSinceNow < -10 {
return
}
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location, regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: false)
}
@IBAction func requestPickUpButton(sender: AnyObject) {
ref = FIRDatabase.database().reference()
let userID: String = FIRAuth.auth()!.currentUser!.uid
ref.child("users").child(userID).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let orderRef = self.ref.child("users").child(userID).child("orders")
let origin = self.pickUpAddress.text!
let destination = self.deliveryAddress.text!
let orderID = orderRef.childByAutoId()
let formatter = NSDateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ";
let defaultTimeZoneStr = formatter.stringFromDate(self.date)
let order = ["date": defaultTimeZoneStr, "origin": origin, "destination": destination]
orderID.setValue(order)
self.currentOrderIDKey = orderID.key as String
print(self.currentOrderIDKey) ///This works!
self.performSegueWithIdentifier("ServiceConfirmation", sender: self)
self.locationManager.stopUpdatingLocation()
})
print(currentOrderIDKey) //this doesnt
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ServiceConfirmation" {
let destinationConroller = segue.destinationViewController as! UINavigationController
let targetController = destinationConroller.topViewController as! ServiceConfirmationViewController
targetController.currentOrderIDKey = "this works"
//this does not : targetController.currentOrderIDKey = currentOrderIDKey
}
}
@IBAction func signOutButton(sender: AnyObject) {
try! FIRAuth.auth()!.signOut()
if let storyboard = self.storyboard {
let viewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController")
self.presentViewController(viewController, animated: false, completion: nil)
}
}
}
作为一个额外的问题,我每次运行应用程序时都会在控制台中收到此警告:
<UILayoutContainerView: ...; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: ....>; layer = <CALayer: ....>>'s window is not equal to <UINavigationController: ....>'s view's window!
提前致谢!
答案 0 :(得分:1)
这是 Asynchrounous
来电的另一个经典案例,即使在分配之前,您也会在currentOrderIDKey
中访问print(currentOrderIDKey)
的值。
即使在
之前,您的print(currentOrderIDKey)
行也会被调用
self.currentOrderIDKey = orderID.key as String
print(self.currentOrderIDKey) ///This works!
被召唤。
ref.child("users").child(userID).observeSingleEventOfType(.Value,..
向您的后端发送 Asynchronous
调用,这需要一些时间来检索数据,但即使在您检索到数据之前,您的print(currentOrderIDKey)
也会获得调用导致null
使用实例化而不是通过performSegue....
进行隔离: -
let secondScene = self.navigationController?.storyboard?.instantiateViewControllerWithIdentifier("ServiceConfirmationViewControllerVC_ID") as! ServiceConfirmationViewController
secondScene.valueTranfered = self. currentOrderIDKey
self.navigationController?.pushViewController(secondScene, animated: true)
ServiceConfirmationViewControllerVC_ID 是你的secondScene storyBoardID
我建议您阅读此内容: - Wikipedia : Asynchronous calls&amp; https://stackoverflow.com/a/748189/6297658