Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios viewDidLoad()swift4.1中的ReverseGeocodeLocation完成用法_Ios_Swift_Reverse Geocoding_Completionhandler - Fatal编程技术网

Ios viewDidLoad()swift4.1中的ReverseGeocodeLocation完成用法

Ios viewDidLoad()swift4.1中的ReverseGeocodeLocation完成用法,ios,swift,reverse-geocoding,completionhandler,Ios,Swift,Reverse Geocoding,Completionhandler,Swift版本:4.1 你好,我在swift方面比初学者多一点。在“按用户位置的订单应用程序”中工作。在用户下订单之前,我通过反向地理位置函数控制用户的“国家”和“城市”名称。并将这些值写入firebase实时数据库childs中 我的数据结构就像 -TR -Ankara -userID -Order(consist of user lat, user long, user mail, userOrder) 用户可以订购和取消他/她的订单。但我还想检

Swift版本:4.1

你好,我在swift方面比初学者多一点。在“按用户位置的订单应用程序”中工作。在用户下订单之前,我通过
反向地理位置函数
控制用户的“国家”和“城市”名称。并将这些值写入firebase实时数据库childs中

我的数据结构就像

 -TR
   -Ankara
       -userID
           -Order(consist of user lat, user long, user mail, userOrder)
用户可以订购和取消他/她的订单。但我还想检查用户是否关闭手机并返回应用程序,应用程序应该检查数据库,如果当前用户发出命令,则必须更改按钮标签、ButtonCancelstate=true以及我们吉祥物的图像

这就是我如何获得订单的user
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
            }
        }
    }
}
我用“订单按钮”中的“国家”和“城市”作为例子

            orderHasBeenCalled = true
            buttonLabelText.text = "CANCEL/EDIT"
            imgView.image = UIImage(named: "...")
            let orderRequestDictionary: [String:Any] = ["..."]
            databaseREF.child(userCountry).child(userCity).child(userID!).setValue(orderRequestDictionary)
它工作完美用户可以发送订单,删除它,即使用户注销它也删除了(整个代码不包括在内)

现在的问题是,我想检查当
viewdiload()
加载我正在使用的这个时,用户是否有订单

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()
        })
   }
现在的问题是,我在internet上读到的
reversegeocode
是异步的或类似的,而且当viewDidLoad()加载“检查是否有顺序的代码”时,它似乎还没有准备好,因为它找不到在childs中搜索姓名的值,所以导致应用程序崩溃

Terminating app due to uncaught exception 'InvalidPathValidation', reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
为了在orderbutton中使用userCountry和userCity,我在viewDidLoad()之前定义了它们

我尝试了很多方法,但没有真正弄清楚如何在viewdidload()中实现反向代码完成。顺便说一句,我也尝试了
viewdideappease()
,但它也给出了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)
        }
    }
}   

我会尽快回复。为了确保,请将
typealias
声明放在要对我的问题进行全局编辑的类的顶部。如果你能在空闲时间登记,那就太棒了。甚至,如果你不能检查,你给我的代码我在任何地方都找不到。我真的很感激。以前是
userLocation
现在是
drinkerLocation
(比user更好的饮酒者,但我认为输入有误)更改
class viewController:。。。{var userLocation=CLLocationCoordinate2D()var locationManager=CLLocationManager()
by
var userLocation=CLLocationCoordinate2D()var locationManager=CLLocationManager()类视图控制器:。。。{
请参见上面的类声明,并更改您的
didUpdateLocation
drinker…否。是因为您正在viewController中重新声明它…我将更新代码
/////////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)
        }
    }
}