I am using MapBoxNavigation.swift in order to build an app that navigates the user to a location. Up to the point where the navigation starts, everything works fine. But when the Navigation starts and MapBoxNavigation.swift emits posts a NSNotification
(see Documentation for how the Library works), the Observer I wrote throws this error message:
app[49184:2686603] -[__NSCFConstantString navProgressDidChange:]: unrecognized selector sent to instance 0x1096dfdb0
This is the code that posts the Notification from MapBoxNavigation.swift:
NotificationCenter.default.post(name: RouteControllerAlertLevelDidChange, object: self, userInfo: [
RouteControllerAlertLevelDidChangeNotificationRouteProgressKey: routeProgress,
RouteControllerAlertLevelDidChangeNotificationDistanceToEndOfManeuverKey: userDistance,
RouteControllerProgressDidChangeNotificationIsFirstAlertForStepKey: isFirstAlertForStep
])
This should be all necessary code:
import Foundation
import UIKit
import Mapbox
import MapboxDirections
import MapboxNavigation
import CoreLocation
import Alamofire
import SWXMLHash
import DateTimePicker
//Primary ViewController, used for basically everything
class ViewController: UIViewController, MGLMapViewDelegate, CLLocationManagerDelegate, UITextFieldDelegate, UIGestureRecognizerDelegate {
lazy var geocoder = CLGeocoder()
@IBOutlet weak var addressTextField: SearchTextField! //SearchTextField
@IBOutlet var mapView: MGLMapView! //MapView of MapBox
@IBOutlet weak var BookingUIView: UIView!
@IBOutlet weak var BookingView: UIView!
//Used to geocode the Addresses
let locationManager = CLLocationManager()
var searched = false
var keyboardEnabled = false
var navigationStarted = false
//Getting the route object
let directions = Directions.shared
let waitForInterval: TimeInterval = 5
@IBOutlet weak var arrivalTimeLabel: UILabel!
@IBOutlet weak var arrivalTimeButton: UIButton!
@IBOutlet weak var leaveTimeButton: UIButton!
@IBOutlet weak var searchAddressButton: UIButton!
/* Overriding Super-Functions */
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// This is needed.... i don't know why..
mapView.delegate = self
//Delegate textField to Self
addressTextField.delegate = self
//Dismiss Keyboard on view Touch
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
self.mapView.addGestureRecognizer(tap)
//Delegate GestureRecognizer to self
tap.delegate = self
//Get the users current location and zoom to it
//Authorization stuff #privacy
self.locationManager.requestWhenInUseAuthorization()
//initialize the updating of the location
if(CLLocationManager.locationServicesEnabled()){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.startUpdatingLocation()
}
//Adding TextViewListener
addressTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
//Registering PresentNavigationViewControllerObserver :3
NotificationCenter.default.addObserver(self, selector: #selector(self.enableNavigationMode), name: NSNotification.Name(rawValue: "StartNavigation"), object: nil)
}
func enableNavigationMode(){
//Hiding some elements here
startNavigation() //Gets called properly
}
func navProgressDidChange(_ userInfo: NSNotification){
print("depart")
print(userInfo)
}
func startNavigation(){
//Get the JSON File via the MapBox API
var lat = locationManager.location?.coordinate.latitude
var long = locationManager.location?.coordinate.longitude
var depart = CLLocation(latitude: lat!, longitude: long!)
var start = Waypoint(coordinate: CLLocationCoordinate2D(latitude: lat!, longitude: long!))
var end = Waypoint(coordinate: CLLocationCoordinate2D(latitude: Shared.shared.selectedParkhouse.latitude, longitude: Shared.shared.selectedParkhouse.longitude))
var string = "https://api.mapbox.com/directions/v5/mapbox/driving-traffic/" + String(describing: long!) + "%2C" + String(describing: lat!) + "%3B" + String(describing: Shared.shared.selectedParkhouse.longitude) + "%2C" + String(describing: Shared.shared.selectedParkhouse.latitude) + ".json?access_token=mykey;)&steps=true"
//Alamofire request works properly
Alamofire.request(string).responseData { response in
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
let jsoninput = self.convertToDictionary(text: utf8Text)!
let jsonroute = (jsoninput["routes"] as! [AnyObject]).first as! [String:Any]
let route = Route(json: jsonroute, waypoints: [start, end], profileIdentifier: MBDirectionsProfileIdentifierAutomobileAvoidingTraffic)
let routecontroller = RouteController(route: route)
print("regging")
NotificationCenter.default.addObserver(RouteControllerAlertLevelDidChange, selector: #selector(self.navProgressDidChange(_:)), name: RouteControllerAlertLevelDidChange, object: routecontroller)
print("resuming")
routecontroller.resume()
print("updating(?)")
//Everything is fine until this function gets called and
//MapBoxNavigation.swift posts a Notification
routecontroller.locationManager(routecontroller.locationManager, didUpdateLocations: [depart])
}
}
}
I used the NotificationCenter
a few times already, that's why i'm coming here for help. I also tried different function names and parameters from no parameters over navProgressDidChange(userInfo: Notification)
to the one that's currently in my code. I don't know the reason why this happens and it also doesn't make sense in my mind, because the selector seems fine to me.
If you need any more information, just ask. Thanks for every answer already!!
Your syntax here is incorrect:
NotificationCenter.default.addObserver(RouteControllerAlertLevelDidChange, selector: #selector(self.navProgressDidChange(_:)), name: RouteControllerAlertLevelDidChange, object: routecontroller)
You're subscribing the string RouteControllerAlertLevelDidChange
to the notification. You meant to subscribe self
. You can see that in the error message:
app[49184:2686603] -[__NSCFConstantString navProgressDidChange:]: unrecognized selector sent to instance 0x1096dfdb0
It's complaining that it's trying to send the message to a constant string.