我有一个使用google的地方api执行api请求的函数。从api响应数据中我捕获一个值并尝试将其设置为变量。此函数在另一个函数内部调用。然后我尝试访问该变量,但不幸的是该变量尚未包含该值。这似乎是一个线程问题,但我不知道如何解决它。
更新: 我已根据回复更新了代码。不幸的是,我仍然无法使用api请求中的值访问变量。我重写了执行api请求以使用完成处理程序的函数。 mapView(mapView:GMSMapView!,didTapInfoWindowOfMarker标记:GMSMarker!)是google maps框架中的一个函数。我是否需要重写这个以使用完成处理程序?
//变量
var website = ""
//使用api请求的代码
func getWebsite2(id: String, completion: (result: String) -> Void) {
var url = NSURL(string: "https://maps.googleapis.com/maps/api/place/details/json?placeid=\(id)&key=AIzaSyAWV1BUFv_vcedYroVrY7DWYuIxcHaqrv0")
self.dataTask = defaultSession.dataTaskWithURL(url!) {
data, respnse, error in
let json : AnyObject
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
var dictionArr = json["result"]
self.website = dictionArr!!["website"] as! String
print(self.website)
}
catch {
print(error)
}
}
self.dataTask?.resume()
}
//第二个功能
func mapView(mapView: GMSMapView!, didTapInfoWindowOfMarker marker: GMSMarker!) {
let storeMarker = marker as! PlaceMarker
self.getWebsite2(storeMarker.id!) {
(result: String) in
print("inside did tap")
print(self.website)
// problem still here
// above two lines of code never run
}
self.performSegueWithIdentifier("toWebView", sender: nil)
}
//我像这样初始化defaultSession和dataTask。
let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
var dataTask: NSURLSessionDataTask?
答案 0 :(得分:1)
您没有调用传递给getWebsite2
函数的完成处理程序。此(伪)代码显示如何获取从服务器接收的字符串并将其传递给didTapInfoWindowOfMarker
中调用的闭包。
func getWebsite2(id: String, completion: (result: String) -> Void) {
self.dataTask = defaultSession.dataTaskWithURL(url!) {
data, response, error in
// now on background thread
let someStringFromNetwork = data[0]
dispatch_async(dispatch_get_main_queue(),{
completion(someStringFromNetwork)
})
}
}
答案 1 :(得分:0)
首先,不要强行展开变量,并始终在需要的地方使用do{} catch{}
。
这个小代码块显示了您应该如何处理try
和if let
条件:
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
if let dictionary = jsonObject["result"] as? [String: String] {
self.website = dictionary["website"]
} else {
print("Parse error")
}
} catch {
print("JSON error: \(error)")
}
其次defaultSession.dataTaskWithURL
是异步请求,只有在他完成时才设置数据。
在另一个世界中,您尝试在请求未完成时打印值。 要解决您的问题,您应该使用Completion Handlers。