【问题标题】:Alamofire with google geocoding api带有谷歌地理编码 api 的 Alamofire
【发布时间】:2015-11-15 14:54:22
【问题描述】:

在我的一个应用程序中,我需要对地址字符串进行地理编码。起初我考虑使用CLGeocoder。然而,在我尝试之后,我偶然发现了我在this 问题中描述的一个问题。

解决方案是改用 Google 的地理编码 API。我现在已经切换到它们并通过以下功能设法让它们工作:

func startConnection(){
    self.data = NSMutableData()
    let urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchBar.text!)&key=MYKEY"
        
    let linkUrl:NSURL = NSURL(string:urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)!
    let request: NSURLRequest = NSURLRequest(URL: linkUrl)
    let connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
        connection.start()
}
    
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
    self.data.appendData(data)
}
    
func connectionDidFinishLoading(connection: NSURLConnection!) {
    do {
        if let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? [String: AnyObject] {
            print(json)
        }
    }
    catch {
        print("error1")
    }
}

这很好用,解决了我在CLGeocoder 中遇到的问题。但是,除了提取地点坐标外,我还需要使用 Google 的 Timezone API 来提取每个地点的时区。

使用NSURLConnectionNSURLSession 执行此操作在我看来有点困难,因为我需要跟踪返回的会话/连接。所以,我想要一些使用完成处理程序的解决方案。

我尝试过使用 Alamofire 框架(使用 Swift 2.0 的正确分支)。但是,在这种情况下,似乎 request() 函数是错误的。我试过了:

let parameters = ["address":searchBar.text!,"key":"MYKEY"]
Alamofire.request(.GET, "https://maps.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.AllowFragments) { _, _, JSON in
            print(JSON)
        }

我得到的只是“成功”。我希望我做错了什么并且可以修复它,因为我真的希望能够使用闭包而不是委托调用。

我的问题是:

  1. 是否可以将 Alamofire 与 Google 地理编码 API 一起使用?
  2. 如果是这样,你能告诉我我做错了什么吗?
  3. 如果不可能,您能否建议我如何设计一个带有NSURSessions 或NSURLConnections 的系统,这样我就可以为每个调用使用完成处理程序而不是委托?

附:我知道我可以使用同步请求,但我真的很想避免使用该选项

更新

建议添加.MutableContainers 作为选项应该使responseJSON 工作。我尝试了以下代码:

let apiKey = "MYKEY"
var parameters = ["key":apiKey,"components":"locality:\(searchBar.text!)"]
Alamofire.request(.GET, "https://maps.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.MutableContainers) { one, two, JSON in
    print(JSON)
}

我得到的只是“成功”。

【问题讨论】:

    标签: ios google-maps-api-3 google-api swift2 alamofire


    【解决方案1】:

    好的,我终于想通了(在@cnoon 的帮助下)。返回的值是Result 类型。我找不到它的文档,但源代码可用here

    为了检索 JSON,可以使用以下实现:

    Alamofire.request(.GET, "https://mapss.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.MutableContainers) { _, _, JSON in
        switch JSON {
    
        case .Failure(_, let error):
            self.error = error
            break
    
        case .Success(let value):
            print(value)
            break
    
        }
    }
    

    打印的value 是地理编码 API 响应的正确表示。

    【讨论】:

    • 这肯定适用于responseJSON。您只需要将自定义读取选项传递给序列化程序。它默认为.AllowFragments,您显然需要.MutableContainers
    • @cnoon 不幸的是它不起作用。请参阅我的问题中的“更新”部分。另外,如果可以的话,你能看看我关于提交beta测试的这个问题吗(这个问题肯定是由于框架引起的)stackoverflow.com/questions/32158112/…
    • 成功意味着IS 工作。在swift-2.0 分支中,responseJSON 现在返回一个 Result 类型,打印时将打印 SUCCESSFAILURE。如果您需要更多信息,请使用debugPrint。查看Result 类型和文档中的示例,了解如何从Result 中获取实际值。
    • @cnoon 谢谢你的评论。我找不到 Result 的文档,但我查看了代码并想出了如何从中提取 JSON。现在将更新我的答案。
    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多