Search code examples
iosswiftxcodegeolocationlocation

Completion handlers for location searches in Swift3


I must have got something wrong - Changed my code to the following but I am still getting an error. I have clearly misunderstood something. Grateful for any help.

 func performSearch()  {
    mapView.delegate = self
    matchingItems.removeAll()
    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = searchText.text
    request.region = mapView.region
    let search = MKLocalSearch(request: request)

    search.start(completionHandler: ({(response: MKLocalSearchResponse?,error: NSError?) in
        if error != nil {
            return
        }
        if response!.mapItems.count == 0 {
            self.resultOfSearch.text = ("No matches found")

        }else{
            self.found = response!.mapItems
            if let items = response?.mapItems, items.count > 0 {
                while self.n < 3 && self.n < response!.mapItems.count { self.locationsRet[(response!.mapItems[self.n].name!)] = self.n; self.n = self.n + 1}
                self.n = 0
            }else{
                self.alert2("NOLOC")
            }

            self.alert3(self.locationsRet, found: self.found)
        }

        } as? MKLocalSearchCompletionHandler)!)
}

But still get that error - what have I done wrong?

This code worked fine in Swift 2 but crashes in Swift 3.

func performSearch()  {
    mapView.delegate = self
    matchingItems.removeAll()
    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = searchText.text
    request.region = mapView.region
    let search = MKLocalSearch(request: request)
    search.start(completionHandler: ({(response: MKLocalSearchResponse?,error: NSError?) in
        if error != nil {
            //self.resultOfSearch.text = ("Error occured in search:\(error!.localizedDescription)")
        } else if response!.mapItems.count == 0 {
            self.resultOfSearch.text = ("No matches found")
            //  }else if response!.mapItems.count > 1 {
        }else{
            self.found = response!.mapItems
            for _ in response!.mapItems {
                if response!.mapItems.count > 0 {
                    while self.n < 3 && self.n < response!.mapItems.count { self.locationsRet[(response!.mapItems[self.n].name!)] = self.n; self.n = self.n + 1}
                    self.n = 0
                }else{
                    self.alert2("NOLOC")

                }
            }
            self.alert3(self.locationsRet, found: self.found)
        }

        } as? MKLocalSearchCompletionHandler)!)
}

This code now gives this error

;

 function signature specialization <preserving fragile attribute, Arg[1] = [Closure Propagated : reabstraction thunk helper from  @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> () to @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> (@out ()), Argument Types : [@callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> ()]> of generic specialization <preserving fragile attribute, ()> of Swift.StaticString.withUTF8Buffer <A> ((Swift.UnsafeBufferPointer<Swift.UInt8>) -> A) -> A
->  0x5bf2e0 <+124>: trap 

Solution

  • Signature of MKLocalSearchCompletionHandler is changed so you need to call the start method on MKLocalSearch like this way.

    search.start { (response: MKLocalSearchResponse?, error: Error?) in
        if error != nil {
            return
        }
        if let items = response?.mapItems, items.count > 0 {
            //access the items using while loop only
        }
        else {
             self.alert2("NOLOC")
        }
    }
    

    Note: In your code there is unnecessary use of for loop, you need simply while loop not the for one.