Swift中的函数错误处理

时间:2016-06-30 01:02:16

标签: swift error-handling

我正在我的CoreLocation和基于MapKit frimeworks的应用程序中实现本地搜索。我正在关注此Tutorial

我收到错误以下错误:

  

无法转换类型的值'(MKLocalSearchResponse!,NSError!) - >   ()'到期望的参数类型'MKLocalSearchCompletionHandler'(又名   '(可选,可选) - > ()')

这是我的代码:

import UIKit
import CoreLocation
import MapKit


class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate{
    private let LocationManager = CLLocationManager()
    let request = MKLocalSearchRequest()
    private var previousPoint:CLLocation?
    private var totalMovementDistance:CLLocationDistance = 0




    @IBOutlet var mapView: MKMapView!


    @IBOutlet var searchText: UITextField!
    var matchingItems: [MKMapItem] = [MKMapItem]()

    @IBAction func textFieldReturn(sender:AnyObject) {
        sender.resignFirstResponder()
        mapView.removeAnnotations(mapView.annotations)
        self.performSearch()

    }

    @IBOutlet var latitudeLabel: UILabel!
    @IBOutlet var longitudeLabel: UILabel!
    @IBOutlet var horizontalAccuracy: UILabel!
    @IBOutlet var altitudeLabel: UILabel!
    @IBOutlet var verticalAccuracyLabel: UILabel!
    @IBOutlet var distanceTraveledLabel: UILabel!






    override func viewDidLoad() {
        super.viewDidLoad()
        LocationManager.delegate = self
        LocationManager.desiredAccuracy = kCLLocationAccuracyBest
        LocationManager.requestWhenInUseAuthorization()



        // Do any additional setup after loading the view, typically from a nib.
    }



    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        print("Authorization Status Changed to \(status.rawValue)")
        switch status {
        case .Authorized, .AuthorizedWhenInUse:
            LocationManager.startUpdatingLocation()
            mapView.showsUserLocation = true

        default:
            LocationManager.stopUpdatingLocation()
            mapView.showsUserLocation = false
        }
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        let errorType = error.code == CLError.Denied.rawValue ? "Access Denied": "Error \(error.code)"
        let alertController = UIAlertController(title: "Location Manager Error", message: errorType, preferredStyle: .Alert)
        let okAction = UIAlertAction(title: "OK", style: .Cancel, handler: {action in})
        alertController.addAction(okAction)
        presentViewController(alertController, animated: true, completion: nil)
    }

    func performSearch() {

        matchingItems.removeAll()
        let request = MKLocalSearchRequest()
        request.naturalLanguageQuery = searchText.text
        request.region = mapView.region

        let search = MKLocalSearch(request: request)

        search.startWithCompletionHandler { (localResponse:MKLocalSearchResponse?, error: NSError?) -> Void in


            if error != nil {
                print("Error occured in search: \(error?.localizedDescription)")
            } else if localResponse == 0 {
                print("No matches found")
            } else {
                print("Matches found")

                for item in localResponse.mapItems  {
                    print("Name = \(item.name)")
                    print("Phone = \(item.phoneNumber)")

                    self.matchingItems.append(item as MKMapItem)
                    print("Matching items = \(self.matchingItems.count)")

                    var annotation = MKPointAnnotation()
                    annotation.coordinate = item.placemark.coordinate
                    annotation.title = item.name
                    self.mapView.addAnnotation(annotation)
                }
            }
        }
    }


    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let newLocation = (locations as [CLLocation]) [locations.count - 1]

        let latitudeString = String(format: "%g\u{00B0}", newLocation.coordinate.latitude)
        latitudeLabel.text = latitudeString

        let longitudeString = String(format: "%g\u{00B0}", newLocation.coordinate.longitude)
        longitudeLabel.text = longitudeString

        let horizontalAccuracyString = String(format: "%gm", newLocation.horizontalAccuracy)
        horizontalAccuracy.text = horizontalAccuracyString

        let altitudeString = String(format: "%gm", newLocation.altitude)
        altitudeLabel.text = altitudeString

        let verticalAccuracyString = String(format: "%gm", newLocation.verticalAccuracy)
        verticalAccuracyLabel.text = verticalAccuracyString

        if newLocation.horizontalAccuracy < 0 {
            //invalid accuracy
            return

        }


        if newLocation.horizontalAccuracy > 100 ||
            newLocation.verticalAccuracy > 50 {
                return
        }

        if previousPoint == nil {
            totalMovementDistance = 0
            let start = Place(title:"Strating Point", subtitle:"This is where we started", coordinate:newLocation.coordinate)
            mapView.addAnnotation(start)
            let region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 100, 100)
            mapView.setRegion(region, animated:true)


        }else {
            print("movement distance: \(newLocation.distanceFromLocation(previousPoint!))")
            totalMovementDistance += newLocation.distanceFromLocation(previousPoint!)

        }

        previousPoint = newLocation

        let distanceString = String(format: "%gm", totalMovementDistance)
        distanceTraveledLabel.text = distanceString



    }



}

错误在这一行:

search.startWithCompletionHandler({(response:
            MKLocalSearchResponse!,

编辑:

enter image description here

3 个答案:

答案 0 :(得分:2)

更换!在参数中? (因为那是方法的签名) 例如:

    search.startWithCompletionHandler { (localResponse:MKLocalSearchResponse?, error:NSError?) -> Void in

    }

答案 1 :(得分:1)

错误消息只是说方法的签名是错误的,因为它需要可选类型。

⇧⌘0并输入MKLocalSearchCompletionHandler确认,然后您会看到

  

typealias MKLocalSearchCompletionHandler =(MKLocalSearchResponse?,   NSError?) - &gt;空隙

所以,它是

search.startWithCompletionHandler({(response:
        MKLocalSearchResponse?,
        error: NSError?) in ...

但你可以 - 而且应该 - 省略类型注释

search.startWithCompletionHandler({(response, error) in ...

答案 2 :(得分:1)

试试这个:

func performSearch() {

    var matchingItems = [MKMapItem]()
    let mapView = MKMapView(frame: CGRectMake(0,0,300,300))

    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "Restaurants 30518"
    request.region = mapView.region

    let search = MKLocalSearch(request: request)

    search.startWithCompletionHandler { (response, error) in

        if let error = error  {
            print("Error occured in search: \(error.localizedDescription)")
        } else if let response = response {
            print("Got response")
            if response.mapItems.count == 0 {
                print("No matches found")
            } else {
                print("Matches found")

                for item in response.mapItems as [MKMapItem] {
                    print("Name = \(item.name)")
                    print("Phone = \(item.phoneNumber)")

                    matchingItems.append(item as MKMapItem)
                    print("Matching items = \(matchingItems.count)")

                    let annotation = MKPointAnnotation()
                    annotation.coordinate = item.placemark.coordinate
                    annotation.title = item.name
                    mapView.addAnnotation(annotation)
                }
            }
        }
    }
}

响应和错误是选项,不要强行打开它们。