如何使用Apple Map Kit实现地址的自动完成

问题描述 投票:16回答:4

我想自动填写用户的地址,与google api在此链接中提供的地址相同:

https://developers.google.com/maps/documentation/javascript/places-autocomplete?hl=en

如何使用Apple地图套件实现相同的功能?

我试过使用Geo Coder,我写了这个例子:

@IBAction func SubmitGeoCode(sender: AnyObject) {

    let address = "1 Mart"
    let coder = CLGeocoder()

    coder.geocodeAddressString(address) { (placemarks, error) -> Void in

        for placemark in placemarks! {

            let lines = placemark.addressDictionary?["FormattedAddressLines"] as? [String]

            for addressline in lines! {
                print(addressline)
            }
        }
    }
}

然而,结果非常令人失望。

任何可用于实现此类功能的Apple API,或者我应该使用google api?

谢谢

ios swift geocoding
4个回答
64
投票

更新 - 我使用Swift 3创建了一个简单的示例项目here,原始答案是用Swift 2编写的。

在iOS 9.3中引入了一个名为MKLocalSearchCompleter的新类,这允许创建自动完成解决方案,您只需传递queryFragment,如下所示:

var searchCompleter = MKLocalSearchCompleter()
searchCompleter.delegate = self
var searchResults = [MKLocalSearchCompletion]()

searchCompleter.queryFragment = searchField.text!

然后使用MKLocalSearchCompleterDelegate处理查询结果:

extension SearchViewController: MKLocalSearchCompleterDelegate {

    func completerDidUpdateResults(completer: MKLocalSearchCompleter) {
        searchResults = completer.results
        searchResultsTableView.reloadData()
    } 

    func completer(completer: MKLocalSearchCompleter, didFailWithError error: NSError) {
        // handle error
    }
}

并以适当的格式显示地址结果:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let searchResult = searchResults[indexPath.row]
    let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: nil)
    cell.textLabel?.text = searchResult.title
    cell.detailTextLabel?.text = searchResult.subtitle
    return cell
}

然后,您可以使用MKLocalCompletion对象来实例化MKLocalSearchRequest,从而获得对MKPlacemark和所有其他有用数据的访问权限:

let searchRequest = MKLocalSearchRequest(completion: completion!)
let search = MKLocalSearch(request: searchRequest)
search.startWithCompletionHandler { (response, error) in
    let coordinate = response?.mapItems[0].placemark.coordinate
}

2
投票

我的答案完全基于@George McDonnell's。我希望对那些在实施最后一个方面遇到麻烦的人有所帮助。

import UIKit
import MapKit

class ViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableVIew: UITableView!

    //create a completer
    lazy var searchCompleter: MKLocalSearchCompleter = {
        let sC = MKLocalSearchCompleter()
        sC.delegate = self
        return sC
    }()

    var searchSource: [String]?
}

extension ViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        //change searchCompleter depends on searchBar's text
        if !searchText.isEmpty {
            searchCompleter.queryFragment = searchText
        }
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchSource?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //I've created SearchCell beforehand; it might be your cell type
        let cell = self.tableVIew.dequeueReusableCell(withIdentifier: "SearchCell", for: indexPath) as! SearchCell

        cell.label.text = self.searchSource?[indexPath.row]
//            + " " + searchResult.subtitle

        return cell
    }
}

extension ViewController: MKLocalSearchCompleterDelegate {
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
        //get result, transform it to our needs and fill our dataSource
        self.searchSource = completer.results.map { $0.title }
        DispatchQueue.main.async {
            self.tableVIew.reloadData()
        }
    }

    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
        //handle the error
        print(error.localizedDescription)
    }
}

1
投票

这个问题的样本项目可以从HERE下载

在此示例项目中,此问题是通过MKLocalSearchRequest和MapKit实现的。

它显示自动填充的地方就像google places API一样,并且可以将注释点放在Apple的地图上(而不是谷歌地图上,我希望这只是你在寻找的。)

但是,它无法显示您从Google Places API获得的准确结果。问题在于地理编码数据库显然并不完整,而苹果并不是领导这一领域的公司 - 谷歌就是。

附加示例应用的一些屏幕截图,以便您可以查看它是否对您的要求有用。

Apple's autocomplete view.

Plotting the annotation point on Apple's map.

希望这就是你要找的!


0
投票

你绝对应该使用Google API。我已经在Apple的地理编码API上挣扎了很长时间,我可以向你保证它们的质量非常有限。

如果你想看到如此低质量的最明显的例子,请检查我的this问题。

使用Google的API,您可以获得更准确的结果。此外,他们还拥有自动完成API。你可以找到更多关于他们here

我试过它们并设法使它们工作得很好。

© www.soinside.com 2019 - 2024. All rights reserved.