ReverseGeocodeLocation 完成在 viewDidLoad() swift4.1 中的使用
ReverseGeocodeLocation completions usage in viewDidLoad() swift4.1
Swift版本:4.1
你好,我比 swift 的初学者还多一点。在 "order application by user locations" 中工作。在用户下订单之前,我通过 reversegeocodelocation function
控制用户 "country" 和 "city" 名称。并将这些值写入 firebase 实时数据库 childs。
我的数据结构是这样的
-TR
-Ankara
-userID
-Order(consist of user lat, user long, user mail, userOrder)
用户可以订购和取消 his/her 订单,我做到了。但我也想检查用户是否关闭了他们的 phone 和 return 应用程序,该应用程序应该检查数据库,如果有当前用户给出的命令 uID
它必须更改按钮标签, buttonToCancelState = true
, 以及我们的吉祥物形象。
这就是我获取用户 coord
订单和 "countrycode" 和 "city" 数据结构名称的方式。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations [0]
if let coord = manager.location?.coordinate {
userLocation = coord
}
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(location) {(placemark, error) in
if error != nil {
print("there is an error")
} else {
var placeMark: CLPlacemark?
placeMark = placemark?[0]
// City
if let city = placeMark?.locality {
self.userCity = city as String
}
// Country
if let country = placeMark?.isoCountryCode {
self.userCountry = country as String
}
}
}
}
我在 "order button" 中使用了这些 "country" 和 "city",例如;
orderHasBeenCalled = true
buttonLabelText.text = "CANCEL/EDIT"
imgView.image = UIImage(named: "...")
let orderRequestDictionary: [String:Any] = ["..."]
databaseREF.child(userCountry).child(userCity).child(userID!).setValue(orderRequestDictionary)
它完美地工作用户可以发送订单,即使用户注销也删除它,(不包括整个代码)
现在的问题是我想在 viewDidLoad()
加载时检查用户是否有订单我正在使用
if let userID = FirebaseAuth.Auth.auth().currentUser?.uid {
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
}
现在的问题是,正如我在互联网上看到的那样 reversegeocode
是异步的或类似的东西,当 viewDidLoad() 加载时它似乎还没有准备好,"code for check if there is order" 使应用程序崩溃,因为它发现在孩子中搜索名字没有价值。
Terminating app due to uncaught exception 'InvalidPathValidation', reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
为了在 orderbutton 中使用 userCountry 和 userCity,我在 viewDidLoad() 之前定义了它们
var userCountry = String()
var userCity = String()
我尝试了很多方法,但没有真正弄清楚如何在 viewdidload() 中完成反向地理编码。我试过 viewDidAppear()
顺便说一句,但它也给 userCountry() 和 userCity() 零。
我希望我的问题清楚易懂。如果以这种方式回答,将不胜感激。在互联网上做了很多研究,有些我尝试过,有些我不明白或不知道我该如何尝试。我希望的最后一个地方是堆栈溢出。至此感谢所有热心回答我问题的人。
我会稍微改变一下方法。使用异步函数后,您必须避免使用同步请求值。
有几种方法可以从异步函数进行嵌套调用,根据您的代码我得出了这种方法,适合您的需要并且它应该可以工作。
/////////attention the scope (must be above class declaration)
typealias CompletionGetAddress = (_ userCity : String?, _ userCountry: String?, _ success: Bool) -> Void
var userLocation = CLLocationCoordinate2D()
var locationManager = CLLocationManager()
//
class viewController: ... {
func viewDidLoad() {
yourLocationManager.requestLocation()
// you should implement some code to ensure your userLocation from your locationManager is not nil and a valid location
if let userID = FirebaseAuth.Auth.auth().currentUser?.uid {
if self.userCity != "" {
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
} else {
getAddress { (city, country, success) in
if success {
self.userCity = city
self.userCountry = country
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
}
}
}
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations [0]
if let coord = manager.location?.coordinate {
userLocation = coord /// attention here
}
}
func getAddress(completion: @escaping CompletionGetAddress) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(userLocation) {(placemark, error) in
if error != nil {
print("there is an error")
completion(nil, nil, false)
} else {
var city: String = ""
var country: String = ""
var placeMark: CLPlacemark?
placeMark = placemark?[0]
// City
if let c = placeMark?.locality {
city = c
}
// Country
if let c = placeMark?.isoCountryCode {
country = c
}
completion(city, country, true)
}
}
}
Swift版本:4.1
你好,我比 swift 的初学者还多一点。在 "order application by user locations" 中工作。在用户下订单之前,我通过 reversegeocodelocation function
控制用户 "country" 和 "city" 名称。并将这些值写入 firebase 实时数据库 childs。
我的数据结构是这样的
-TR
-Ankara
-userID
-Order(consist of user lat, user long, user mail, userOrder)
用户可以订购和取消 his/her 订单,我做到了。但我也想检查用户是否关闭了他们的 phone 和 return 应用程序,该应用程序应该检查数据库,如果有当前用户给出的命令 uID
它必须更改按钮标签, buttonToCancelState = true
, 以及我们的吉祥物形象。
这就是我获取用户 coord
订单和 "countrycode" 和 "city" 数据结构名称的方式。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations [0]
if let coord = manager.location?.coordinate {
userLocation = coord
}
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(location) {(placemark, error) in
if error != nil {
print("there is an error")
} else {
var placeMark: CLPlacemark?
placeMark = placemark?[0]
// City
if let city = placeMark?.locality {
self.userCity = city as String
}
// Country
if let country = placeMark?.isoCountryCode {
self.userCountry = country as String
}
}
}
}
我在 "order button" 中使用了这些 "country" 和 "city",例如;
orderHasBeenCalled = true
buttonLabelText.text = "CANCEL/EDIT"
imgView.image = UIImage(named: "...")
let orderRequestDictionary: [String:Any] = ["..."]
databaseREF.child(userCountry).child(userCity).child(userID!).setValue(orderRequestDictionary)
它完美地工作用户可以发送订单,即使用户注销也删除它,(不包括整个代码)
现在的问题是我想在 viewDidLoad()
加载时检查用户是否有订单我正在使用
if let userID = FirebaseAuth.Auth.auth().currentUser?.uid {
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
}
现在的问题是,正如我在互联网上看到的那样 reversegeocode
是异步的或类似的东西,当 viewDidLoad() 加载时它似乎还没有准备好,"code for check if there is order" 使应用程序崩溃,因为它发现在孩子中搜索名字没有价值。
Terminating app due to uncaught exception 'InvalidPathValidation', reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
为了在 orderbutton 中使用 userCountry 和 userCity,我在 viewDidLoad() 之前定义了它们
var userCountry = String()
var userCity = String()
我尝试了很多方法,但没有真正弄清楚如何在 viewdidload() 中完成反向地理编码。我试过 viewDidAppear()
顺便说一句,但它也给 userCountry() 和 userCity() 零。
我希望我的问题清楚易懂。如果以这种方式回答,将不胜感激。在互联网上做了很多研究,有些我尝试过,有些我不明白或不知道我该如何尝试。我希望的最后一个地方是堆栈溢出。至此感谢所有热心回答我问题的人。
我会稍微改变一下方法。使用异步函数后,您必须避免使用同步请求值。
有几种方法可以从异步函数进行嵌套调用,根据您的代码我得出了这种方法,适合您的需要并且它应该可以工作。
/////////attention the scope (must be above class declaration)
typealias CompletionGetAddress = (_ userCity : String?, _ userCountry: String?, _ success: Bool) -> Void
var userLocation = CLLocationCoordinate2D()
var locationManager = CLLocationManager()
//
class viewController: ... {
func viewDidLoad() {
yourLocationManager.requestLocation()
// you should implement some code to ensure your userLocation from your locationManager is not nil and a valid location
if let userID = FirebaseAuth.Auth.auth().currentUser?.uid {
if self.userCity != "" {
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
} else {
getAddress { (city, country, success) in
if success {
self.userCity = city
self.userCountry = country
databaseRef.child(userCountry).child(userCity).queryOrdered(byChild: userID!).observe(.childAdded, with: { (snapshot) in
self.OrderHasBeenCalled = true
self.buttonLabelText.text = "CANCEL/EDIT"
self.imgView.image = UIImage(named: "...")
databaseRef.child(self.userCountry).child(self.userCity).removeAllObservers()
})
}
}
}
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations [0]
if let coord = manager.location?.coordinate {
userLocation = coord /// attention here
}
}
func getAddress(completion: @escaping CompletionGetAddress) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(userLocation) {(placemark, error) in
if error != nil {
print("there is an error")
completion(nil, nil, false)
} else {
var city: String = ""
var country: String = ""
var placeMark: CLPlacemark?
placeMark = placemark?[0]
// City
if let c = placeMark?.locality {
city = c
}
// Country
if let c = placeMark?.isoCountryCode {
country = c
}
completion(city, country, true)
}
}
}