web-dev-qa-db-fra.com

Comment mettre en œuvre l'auto-complétion d'adresse avec Apple Map Kit

Je souhaite renseigner automatiquement l'adresse de l'utilisateur de la même manière que ce que google api fournit dans ce lien:

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

Comment puis-je implémenter la même fonctionnalité en utilisant Apple Map Kit?

J'ai essayé d'utiliser le Geo Coder, j'ai écrit ceci par exemple:

@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)
            }
        }
    }
}

Cependant, les résultats sont très décevants.

Toute API Apple disponible pour implémenter une telle fonctionnalité, ou devrais-je me diriger vers Google Api?

Je vous remercie

14

Update - J'ai créé un exemple de projet simple ici en utilisant Swift 3 comme la réponse d'origine était écrite dans Swift 2.

Dans iOS 9.3, une nouvelle classe appelée MKLocalSearchCompleter a été introduite, ce qui permet de créer une solution de saisie semi-automatique. Il vous suffit de passer le queryFragment comme ci-dessous:

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

searchCompleter.queryFragment = searchField.text!

Puis manipulez les résultats de la requête en utilisant la variable MKLocalSearchCompleterDelegate:

extension SearchViewController: MKLocalSearchCompleterDelegate {

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

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

Et afficher les résultats de l'adresse dans un format approprié:

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
}

Vous pouvez ensuite utiliser un objet MKLocalCompletion pour instancier une MKLocalSearchRequest, en obtenant ainsi un accès à MKPlacemark et à toutes les autres données utiles:

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

Ma réponse est entièrement basée sur celle de @George McDonnell. J'espère que cela aidera les gars qui ont du mal à mettre en œuvre le dernier.

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)
    }
}
2
Gogi

Vous devriez absolument vous diriger vers les API Google. Je me suis longtemps battu avec les API de géocodage d’Apple et je peux vous assurer qu’elles sont de qualité très limitée.

Si vous voulez voir l'exemple le plus clair d'une telle qualité médiocre, vérifiez cette question que je vous pose. 

Avec les API de Google, vous pouvez obtenir des résultats beaucoup plus précis. En outre, ils ont des API de saisie semi-automatique. Vous pouvez en savoir plus à leur sujet ici .

Je les ai essayés et j'ai réussi à les faire fonctionner assez bien.

1
Andriy Gordiychuk

UN EXEMPLE DE PROJET POUR CE NUMERO PEUT ÊTRE TÉLÉCHARGE À PARTIR DE ICI

Dans cet exemple de projet, ce problème est résolu par MKLocalSearchRequest et MapKit.

Il affiche des lieux de saisie semi-automatique, comme l’API Google Places, et peut placer le point d’annotation sur la carte d’Apple (et non sur la carte Google, j’espère que c’est uniquement ce que vous recherchez.)

Toutefois, les résultats ne sont pas aussi précis que ce que vous pouvez obtenir de l'API Google Adresses. Le problème est que la base de données de géocodage n’est évidemment pas complète et qu’Apple n’est pas la société qui mène ce domaine, mais Google.

Joindre des captures d’écran de l’exemple d’application afin que vous puissiez voir s’il est utile ou non. 

 Apple's autocomplete view.

 Plotting the annotation point on Apple's map.

J'espère que c'est ce que vous recherchez!

1
Apekshit