Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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
Swift 将反向地理编码的结果分配给全局变量_Swift_Closures_Global Variables_Nsmutableattributedstring_Mkreversegeocoder - Fatal编程技术网

Swift 将反向地理编码的结果分配给全局变量

Swift 将反向地理编码的结果分配给全局变量,swift,closures,global-variables,nsmutableattributedstring,mkreversegeocoder,Swift,Closures,Global Variables,Nsmutableattributedstring,Mkreversegeocoder,我使用的是Swift 4和Xcode 9.3.1。我包括了代码的截图 一般来说,我对移动开发/编程不熟悉,一直在思考如何表达这一点。这是我能解释的最好的解释: 我正在构建一个应用程序,获取用户的位置,以便向他们发送帮助。该应用程序获取用户的坐标,并显示一个包含用户地址信息的文本视图。非常简单的mapKit/coreLocation功能。到目前为止,很好:使用startUpdatingLocation()获取坐标效果很好,我使用反向地理编码器获取了街道名称和位置。但是它们——意思是解码的街道和地区

我使用的是Swift 4和Xcode 9.3.1。我包括了代码的截图

一般来说,我对移动开发/编程不熟悉,一直在思考如何表达这一点。这是我能解释的最好的解释:

我正在构建一个应用程序,获取用户的位置,以便向他们发送帮助。该应用程序获取用户的坐标,并显示一个包含用户地址信息的文本视图。非常简单的mapKit/coreLocation功能。到目前为止,很好:使用startUpdatingLocation()获取坐标效果很好,我使用反向地理编码器获取了街道名称和位置。但是它们——意思是解码的街道和地区字符串——只有在闭包内调用它们时才会打印出来,而不是在闭包外。我理解(正确或错误?)一个类中需要用于多个函数的变量应该在顶部全局声明。但是,我不知道如何从这个闭包中提取信息以便在其他地方使用

我一直在用谷歌搜索和阅读stackOverflow中的问题,我觉得有一些非常简单的东西缺失了,但却不知道是什么。到目前为止我尝试过但未成功的事情:

1\在类的开头将全局变量定义为空字符串 在发生地理编码反转方法的闭包内使用变量名,试图存储结果字符串,但当我尝试打印闭包外的变量时,全局变量仍然是空字符串(“”)

[顶部声明的全局变量][1]

2_定义一个空的、全局的字符串数组,并将闭包内部的信息附加到全局数组中。在闭包外仍然有一个空数组。(与第1条相同)

3_创建一个函数--func decodedString()--以将数据返回为字符串,这样我就可以通过声明

*let streetLocation : String = decodedString()*
但是,当我这样声明该函数时:

var street = ""
var locality = ""

// Get the street address from the coordinates
    func deocodedString() -> String {
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location) { placemarks, error in
        if let placemark = placemarks?.first {
        self.street = placemark.name!
        self.locality = placemark.locality!
        let string = "\(self.street), \(self.locality)"
        return string
        }
    }
}
func mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker) {
    GoogleAPI.sharedInstance.geocoding(lat: marker.position.latitude, long: marker.position.longitude)
    DispatchQueue.main.async {
        self.txtSearch.text = GoogleAPI.sharedInstance.addressValue
    }
}
我在void函数中得到一个错误:意外的非void返回值

最后,如果我使用下面的代码将信息直接传递到闭包中的TextView中,我的TextView将成功更新——但我无法格式化字符串,我需要这样做才能使它们看起来像我遵循的设计说明(即一些粗体文本、一些常规文本和一些不同大小的文本):

这就是为什么我不能用textView.text=string方法传递它


我非常感谢您的帮助…我一直在查看StackOverFlow、youtube和其他教程位置,但我不知道我缺少了什么,也不知道为什么我的函数声明会产生错误。在过去的24小时里,我已经多次销毁和反转了我的代码,没有得到一个独立的字符串,在将其传递到textView之前,我可以对其应用格式,我不知道如何处理它

调用此函数时,reverseGeocodeLocation将在后台线程中运行。因此,如果您想在这个方法中返回地址,您应该使用


在更新地图屏幕上的标签时,我遇到了谷歌地理编码器的问题

所以我做了这个,首先,创造

swift文件名:GoogleAPI随意调用

class GoogleAPI {

    static let sharedInstance = GoogleAPI()

    private init() { }

    var addressValue = ""

    public func geocoding(lat: Double, long: Double) {
        Alamofire.request("https://maps.googleapis.com/maps/api/geocode/json?latlng=\(lat),\(long)&key=YOUR_GOOGLE_KEY").responseJSON { (response) in
            if response.result.isSuccess {
                let dataJSON : JSON = JSON(response.result.value!)
                self.geocoding(json: dataJSON)
            } else {
                print("Error \(response.result.error!)")
            }
        }
    }

    fileprivate func geocoding(json: JSON) {
        let json = json["results"]
        let address = json[1]["formatted_address"].stringValue
        addressValue = address
        print("pin address \(addressValue)")
    }
}
这是一个对Google的API调用,用于从响应中获取所有内容并解析唯一的街道

之后,使用地图转到视图控制器,其中有pin、地图等

设置一个可拖动的针、标记。[
marker1.isDraggable=true
]

然后添加这个函数

地图视图(地图视图:GMSMapView,双端拖动标记:GMSMarker)

并添加来自上面的呼叫,如下所示:

var street = ""
var locality = ""

// Get the street address from the coordinates
    func deocodedString() -> String {
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location) { placemarks, error in
        if let placemark = placemarks?.first {
        self.street = placemark.name!
        self.locality = placemark.locality!
        let string = "\(self.street), \(self.locality)"
        return string
        }
    }
}
func mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker) {
    GoogleAPI.sharedInstance.geocoding(lat: marker.position.latitude, long: marker.position.longitude)
    DispatchQueue.main.async {
        self.txtSearch.text = GoogleAPI.sharedInstance.addressValue
    }
}
txtSearch是我的搜索文本字段

是的,我知道,这可以做得更好,但没有时间。这是有效的


Swift 4.2

非常感谢您识别问题并包括该文章!我现在理解了守则的第一部分(第一段),但我仍然对守则第二段的逻辑感到困惑。以self.getAddress开头的那个。。。将它合并到我的代码中,我会得到一个错误:类型为“ViewController”的值没有成员“getaddress”。你介意对这三行代码做一个简短的评论吗?第一段getaddress是一个以闭包作为参数(完成)的函数。您需要按照第2段调用此函数。当您调用此函数时,它会尝试获取地址字符串并调用闭包。闭包可以用作函数的返回类型、参数。{print中的地址(address)self.addressTextView.text=address}。这是调用完成(字符串)时将执行的闭包