Binayak Pandey Binayak Pandey - 1 year ago 84
Swift Question

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?

Rob Rob
Answer Source

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
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download