2017-07-26 4 views
1

Je suis en train de créer un clone de Uber en utilisant Firebase mais je continue à obtenir une erreur dans mon MapViewController ceci est mon code:Impossible d'attribuer une valeur de type 'MapViewController' à un type 'UberController?'

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? a été déclaré dans un autre fichier Swift et c'est le code pour que:

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]); 
    } 

} 

Mon erreur est: Cannot assign value of type 'mapViewController' to type 'UberController?' dans le mapViewController. Je ne sais pas ce que je fais mal. Des idées?

Répondre

0

Vous devez déclarer votre MapViewController pour se conformer au protocole UberController, tout comme vous déclarez la conformité à MapViewDelegate et CLLocationManagerDelegate protocoles.

Soit:

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

Ou, mieux encore:

class MapViewController: UIViewController { 
    ... 
} 

extension MapViewController: MKMapViewDelegate { 
    // MKMapViewDelegate methods here 
} 

extension MapViewController: CLLocationManagerDelegate { 
    // CLLocationManagerDelegate methods here 
} 

extension MapViewController: UberController { 
    // UberController methods here 
}