Adding items into Objects

314 views Asked by At

I'm looking to be able to append a personal location into the MKLocationSearchCompletion array that will can be found when the user searches through the search bar. However, I am having trouble understanding how items are stored into objects and whether I can add a placemark object (or location information) into the MKLocationSearch object. What I've been able to garner from the documentation is that the MKLocalSearchCompleter object stores strings that are accessed when the user types in partial strings into the search bar. But I am not sure where I can access this array and add new locations.

Here is how the code is structured to display search completion results:

var searchCompleter = MKLocalSearchCompleter()
var searchResults = [MKLocalSearchCompletion]()

@IBOutlet weak var searchBar: UISearchBar!

override func viewDidLoad() {
    searchCompleter.delegate = self
    searchBar.delegate = self
}

extension ViewController: MKLocalSearchCompleterDelegate {
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
        searchResults = completer.results
        searchResultsTableView.reloadData()
    }

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

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchResults.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let searchResult = searchResults[indexPath.row]
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)

        cell.textLabel?.attributedText = highlightedText(searchResult.title, inRanges: searchResult.titleHighlightRanges, size: 17.0)
        cell.detailTextLabel?.attributedText = highlightedText(searchResult.subtitle, inRanges: searchResult.subtitleHighlightRanges, size: 12.0)

        return cell
    }
}

extension ViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchCompleter.queryFragment = searchText
    }

    func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
        self.searchBar.endEditing(true)
        searchBar.resignFirstResponder()
        return true
    }
}
1

There are 1 answers

1
cldrr On

I don't think that you can add your own locations and POIs to MapKit, but:

1) I would suggest you create an own enum

class CustomSearchResult {
    let title: String
    ...
}

enum SearchResultType {
    case localSearchResult(result: MKLocalSearchCompletion)
    case customResult(result: CustomSearchResult)
}

2) And you have your array of results:

var searchResults = [SearchResultType]()

3) In completerDidUpdateResults you can add your personal results and the MapKit results into your searchResults array:

searchResults = completer.results.map { 
   SearchResultType.localSearchResult(result: $0) }

// Add here custom results
searchResults.append(SearchResultType.customResult(result: 
    CustomSearchResult(title: "test")))

4) ..and in cellForRowAtIndexPath you can decide whether you have custom or MapKit result:

let searchResult = searchResults[indexPath.row]
switch searchResult {
case .customResult(let result):
    cell.textLabel.text = result.title
case .localSearchResult(let result):
    cell.textLabel.text = result.title
}