简体   繁体   中英

Cannot assign value of type 'MapViewController' to type 'UberController?'

So I am trying to create a clone of Uber using Firebase but I keep getting an error in my MapViewController this is my code:

import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {


    @IBOutlet weak var callUberBtn: UIButton!
    @IBOutlet weak var myMap: MKMapView!

    private var locationManager = CLLocationManager();
    private var userLocation: CLLocationCoordinate2D?;
    private var driverLocation: CLLocationCoordinate2D?;

    private var timer = Timer();

    private var canCallUber = true;
    private var riderCanceledRequest = false;

    private var appStartedForTheFirstTime = true;

    override func viewDidLoad() {
        super.viewDidLoad()
        initializeLocationManager();
        UberHandler.Instance.observeMessagesForRider();
        UberHandler.Instance.delegate = self;  //Cannot assign value of type 'mapViewController' to type 'UberController?'
    }

    private func initializeLocationManager() {
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        locationManager.requestWhenInUseAuthorization();
        locationManager.startUpdatingLocation();
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        // if we have the coordinates from the manager
        if let location = locationManager.location?.coordinate {

            userLocation = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)

            let region = MKCoordinateRegion(center: userLocation!, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01));

            myMap.setRegion(region, animated: true);

            myMap.removeAnnotations(myMap.annotations);

            if driverLocation != nil {
                if !canCallUber {
                    let driverAnnotation = MKPointAnnotation();
                    driverAnnotation.coordinate = driverLocation!;
                    driverAnnotation.title = "Driver Location";
                    myMap.addAnnotation(driverAnnotation);
                }
            }

            let annotation = MKPointAnnotation();
            annotation.coordinate = userLocation!;
            annotation.title = "Drivers Location";
            myMap.addAnnotation(annotation);

        }

    }

    func updateRidersLocation() {
        UberHandler.Instance.updateRiderLocation(lat: userLocation!.latitude, long: userLocation!.longitude);
    }

    func canCallUber(delegateCalled: Bool) {
        if delegateCalled {
            callUberBtn.setTitle("Cancel Uber", for: UIControlState.normal);
            canCallUber = false;
        } else {
            callUberBtn.setTitle("Call Uber", for: UIControlState.normal);
            canCallUber = true;
        }
    }

    func driverAcceptedRequest(requestAccepted: Bool, driverName: String) {

        if !riderCanceledRequest {
            if requestAccepted {
                alertTheUser(title: "Uber Accepted", message: "\(driverName) Accepted Your Uber Request")
            } else {
                UberHandler.Instance.cancelUber();
                timer.invalidate();
                alertTheUser(title: "Uber Canceled", message: "\(driverName) Canceled Uber Request")
            }
        }
        riderCanceledRequest = false;
    }

    func updateDriversLocation(lat: Double, long: Double) {
        driverLocation = CLLocationCoordinate2D(latitude: lat, longitude: long);
    }

    @IBAction func callUber(_ sender: Any) {
        if userLocation != nil {
            if canCallUber {
                UberHandler.Instance.requestUber(latitude: Double(userLocation!.latitude), longitude: Double(userLocation!.longitude))

                timer = Timer.scheduledTimer(timeInterval: TimeInterval(10), target: self, selector: #selector(MapViewController.updateRidersLocation), userInfo: nil, repeats: true);

            } else {
                riderCanceledRequest = true;
                UberHandler.Instance.cancelUber();
                timer.invalidate();
            }
        }
    }

    private func alertTheUser(title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert);
        let ok = UIAlertAction(title: "OK", style: .default, handler: nil);
        alert.addAction(ok);
        present(alert, animated: true, completion: nil);
    }
}

UberController? was declared in another Swift file and this is the code for that:

import Foundation
import FirebaseDatabase

protocol UberController: class {
    func canCallUber(delegateCalled: Bool);
    func driverAcceptedRequest(requestAccepted: Bool, driverName: String);
    func updateDriversLocation(lat: Double, long: Double);
}

class UberHandler {
    private static let _instance = UberHandler();

    weak var delegate: UberController?;

    var rider = "";
    var driver = "";
    var rider_id = "";

    static var Instance: UberHandler {
        return _instance;
    }

    func observeMessagesForRider() {
        // RIDER REQUESTED UBER
        DBProvider.Instance.requestRef.observe(DataEventType.childAdded) { (snapshot: DataSnapshot) in

            if let data = snapshot.value as? NSDictionary {
                if let name = data[Constants.NAME] as? String {
                    if name == self.rider {
                        self.rider_id = snapshot.key;
                        self.delegate?.canCallUber(delegateCalled: true);
                    }
                }
            }

        }

        // RIDER CANCELED UBER
        DBProvider.Instance.requestRef.observe(DataEventType.childRemoved) { (snapshot: DataSnapshot) in

            if let data = snapshot.value as? NSDictionary {
                if let name = data[Constants.NAME] as? String {
                    if name == self.rider {
                        self.delegate?.canCallUber(delegateCalled: false);
                    }
                }
            }

        }

        // DRIVER ACCEPTED UBER
        DBProvider.Instance.requestAcceptedRef.observe(DataEventType.childAdded) { (snapshot: DataSnapshot) in

            if let data = snapshot.value as? NSDictionary {
                if let name = data[Constants.NAME] as? String {
                    if self.driver == "" {
                        self.driver = name;
                        self.delegate?.driverAcceptedRequest(requestAccepted: true, driverName: self.driver);
                    }
                }
            }

        }

        // DRIVER CANCELED UBER
        DBProvider.Instance.requestAcceptedRef.observe(DataEventType.childRemoved) { (snapshot:DataSnapshot) in

            if let data = snapshot.value as? NSDictionary {
                if let name = data[Constants.NAME] as? String {
                    if name == self.driver {
                        self.driver = "";
                        self.delegate?.driverAcceptedRequest(requestAccepted: false, driverName: name);
                    }
                }
            }

        }

        // DRIVER UPDATING LOCATION
        DBProvider.Instance.requestAcceptedRef.observe(DataEventType.childChanged) { (snapshot: DataSnapshot) in

            if let data = snapshot.value as? NSDictionary {
                if let name = data[Constants.NAME] as? String {
                    if name == self.driver {
                        if let lat = data[Constants.LATITUDE] as? Double {
                            if let long = data[Constants.LONGITUDE] as? Double {
                                self.delegate?.updateDriversLocation(lat: lat, long: long);
                            }
                        }
                    }
                }
            }

        }

    }

    func requestUber(latitude: Double, longitude: Double) {
        let data: Dictionary<String, Any> = [Constants.NAME: rider, Constants.LATITUDE: latitude, Constants.LONGITUDE: longitude];
        DBProvider.Instance.requestRef.childByAutoId().setValue(data);
    } // request uber

    func cancelUber() {
        DBProvider.Instance.requestRef.child(rider_id).removeValue();
    }

    func updateRiderLocation(lat: Double, long: Double) {
        DBProvider.Instance.requestRef.child(rider_id).updateChildValues([Constants.LATITUDE: lat, Constants.LONGITUDE: long]);
    }

}

My error is: Cannot assign value of type 'mapViewController' to type 'UberController?' in the mapViewController . I don't know what I'm doing wrong. Any ideas?

You have to declare your MapViewController to conform to UberController protocol, just like you declare conformance to MapViewDelegate and CLLocationManagerDelegate protocols.

Either:

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UberController { 
    ...
}

Or, even better:

class MapViewController: UIViewController { 
    ...
}

extension MapViewController: MKMapViewDelegate {
    // MKMapViewDelegate methods here
}

extension MapViewController: CLLocationManagerDelegate {
    // CLLocationManagerDelegate methods here
}

extension MapViewController: UberController {
    // UberController methods here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM