像 Apple Weather 应用程序一样的击键位置查找

Location Lookup on Keystroke like Apple Weather app

我想像 Apple Weather 应用程序一样执行位置查找,它会在每次击键时显示 table 个潜在位置。每次在文本字段中发生 "editing changed" 事件时,我都会将用户的输入字符串发送到下面的函数。该字符串似乎已正确发送,但我没有取回预期的地标数组。例如 "Chestnut" returns 只有 "Chestnut, IL",但如果我输入 "Chestnut Hi",我会得到四个元素:"Marshfield, MA"、"Wilbraham, MA"、"South Hadley, MA" , 和 "Greenfield, MA"。然后输入 "Chesnut Hil" returns "Brookline, MA",它甚至不在 "Chestnut Hi" 列表中。代码如下。非常感谢!

func forwardGeocoding(address: String) {
    CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
        if error != nil {
            print(error!)
            return
        }
        var placeName = ""
        var placeCoordinate = ""
        self.placeNames = [] // empty arrays at the start of each geocode result
        self.placeCoordinates = []

        if (placemarks?.count)! > 0 {

            for placemark in placemarks! {

                if placemark.country != "United States" {
                    let city = placemark.locality ?? ""
                    let country = placemark.country ?? ""
                    placeName = "\(city) \(country)"
                } else {
                    let city = placemark.locality ?? ""
                    placeName = "\(city), \(placemark.administrativeArea!)"
                }

                let coordinate = placemark.location?.coordinate
                placeCoordinate = "\(coordinate!.latitude), \(coordinate!.longitude)"
                self.placeNames.append(placeName)
                self.placeCoordinates.append(placeCoordinate)
            }
        }
        self.tableView.reloadData()
    })
}

来自 CLGeocoder docs 的一些值得注意的片段,添加了重点:

A geocoder object is a single-shot object that works with a network-based service to look up placemark information for its specified coordinate value


Applications should be conscious of how they use geocoding. Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail.


The computer or device must have access to the network in order for the geocoder object to return detailed placemark information

所有这些都表明 a) 使用 CLGeocoder 到 return 并优化 "as you type" 搜索结果通常可能效果不佳,并且 b) 因此可能不是苹果在天气中使用的。

请记住,Weather 不想将用户输入的字符串映射到地球上的 lat/longs — 它是针对 地名列表 进行搜索。 (具体来说,是 Apple 的天气预报合作伙伴提供数据的地点列表。)如果这是您要搜索的内容,您将需要自己的此类列表。

如果您想要 "as you type" 搜索结果,最好由本地数据库提供服务,或者至少是为该用途量身定制的 Web 服务。如 this old answer, there are plenty of options for that — Google offers some services, and GeoNames.org 中所述,free/open 选项具有网络服务和可下载的数据库,您可以将它们嵌入到您的应用程序中。

一旦您拥有了这样的 database/service,您还需要考虑如何使用它。例如,您要 "chestnut hi" 查找宾夕法尼亚州切斯特纳特山还是(假设;没有)夏威夷切斯特纳特?您如何预处理搜索字符串并将它们放入数据库查询中将影响您的结果。