Getting this error when using MKMapView! : "fatal error unexpectedley found nil while unwrapping optional value" - ios

Im trying to show the user's location and a map of the location using MKMapView but I get an error when doing so. I get an error for this line of code: map.delegate = self. Here's the full code, can someone tell me what I'm doing wrong. I looked at other tutorials and they have it the same way I have it setup and it works for them. Thank you!
import Foundation
import SpriteKit
import CoreLocation
import MapKit
class MapScene: SKScene, CLLocationManagerDelegate, MKMapViewDelegate {
var locationMangaer = CLLocationManager()
var map : MKMapView!
override func didMoveToView(view: SKView) {
locationMangaer.delegate = self
locationMangaer.desiredAccuracy = kCLLocationAccuracyBest
locationMangaer.requestWhenInUseAuthorization()
locationMangaer.startUpdatingLocation()
locationMangaer.requestAlwaysAuthorization()
map.delegate = self
map.showsUserLocation = true
}
//DELEGATE METHODS
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("error")
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var userLocation: CLLocation = locations[0] as! CLLocation
locationMangaer.stopUpdatingLocation()
let location = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location, span: span)
map.setRegion(region, animated: true)
map.centerCoordinate = userLocation.coordinate
println("call")
}

When you declare your map variable, you do not provide a default value, and it doesn't instantiate properly.
What you need to do is hook it up to a view in your storyboard with an #IBOutlet,
#IBOutlet weak var map : MKMapView!
or if you are manually creating your view hierarchy, instantiate a MKMapView with a default value.
var map : MKMapView! = MKMapView()
I recommend the former.

Tried your code. Make it work with the following changes:
Comment out
locationMangaer.requestAlwaysAuthorization()
Comment out
mapView.centerCoordinate = userLocation.coordinate
Add the following String entry to Info.plist:
NSLocationWhenInUseUsageDescription
with any text.

Related

App crashes when run more than once on GMSMAPVIEW

I have an app that finds places near the user’s location, however, the app crashes the second time it runs with the exception:
fatal error: unexpectedly found nil while unwrapping an Optional value.
On line:
self.googleMapView.animate(toLocation: coordinates)
I checked and the googleMapView is nil but I don’t understand how it is nil or how it ran the first time. It only starts crashing on subsequent tries if I delete and reinstall the app it works fine on the first try but after that it keeps crashing even if I restart the app. Full code below
import UIKit
import GoogleMaps
import GooglePlacePicker
import MapKit
class MapViewController: UIViewController, CLLocationManagerDelegate {
var currentLongitude: CLLocationDegrees = 0
var currentLatitude: CLLocationDegrees = 0
var locationManager: CLLocationManager!
var placePicker: GMSPlacePickerViewController!
var googleMapView: GMSMapView!
#IBOutlet weak var mapViewContainer: MKMapView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.googleMapView = GMSMapView(frame: self.mapViewContainer.frame)
self.googleMapView.animate(toZoom: 18.0)
self.view.addSubview(googleMapView)
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location:CLLocation = locations.last {
self.currentLatitude = location.coordinate.latitude
self.currentLongitude = location.coordinate.longitude
}
else {
print("Location Error")
}
let coordinates = CLLocationCoordinate2DMake(self.currentLatitude, self.currentLongitude)
let marker = GMSMarker(position: coordinates)
marker.title = "I am here"
marker.map = self.googleMapView
self.googleMapView.animate(toLocation: coordinates)
}
private func locationManager(manager: CLLocationManager,
didFailWithError error: Error){
print("An error occurred while tracking location changes : \(error.localizedDescription)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Crash is pretty self-explanatory:
You are setting your location's delegate in the viewDidLoad but creating the map in the viewDidAppear.
If the location was known by iOS, you will receive the message before viewDidAppear call so in the line : self.googleMapView.animate(toLocation: coordinates), your map is still nil
You can either define your map as optional : var googleMapView: GMSMapView?, or you can wait for your map to be defined to create your location Manager.

Downcast from 'CLLocation?' to 'CLLocation' only unwraps optionals; did you mean to use '!'?

I'm trying to display the users current location on a map view but I'm getting an error on the first line of the location manager function
Here is my code
import UIKit
import MapKit
class FirstViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapkitView: MKMapView!
var locationManager: CLLocationManager!
override func viewDidLoad()
{
super.viewDidLoad()
if (CLLocationManager.locationServicesEnabled())
{
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last as! CLLocation
let center = CLLocationCoordinate2DMake(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapkitView.setRegion(region, animated: true)
}
}
The error I'm getting is "Downcast from 'CLLocation?' to 'CLLocation' only unwraps optionals; did you mean to use '!'?
on line let location = locations.last as! CLLocation
You are force-casting an Optional CLLocationto CLLocation, that is why Swift suggests to simply force unwrap it:
let location = locations.last!
This version (and yours) will crash if locations is empty.
Thus I recommend to never force unwrap anything and use guardinstead:
guard let location = locations.last else {
return
}

User location won't come up in simulator in Xcode

I'm new to app development and I'm trying to get the user location to come up in the simulator but I keep getting the Use of unresolved identifier error. I have looked at other questions, which are very specific to their own projects, and have tried to approach my own app in a similar way but to not avail. Any help, por favor? Here's my code, and a link to a screenshot of Xcode.
import UIKit
import MapKit
import CoreLocation
class SecondViewController: UIViewController, CLLocationManagerDelegate {
//Map
#IBOutlet weak var map: MKMapView!
let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{ let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
self.map.showsUserLocation = true
}
override func viewDidLoad()
{
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
//This is where I get an error
map.setRegion(region, animated: true)**
}
Error: Use of unresolved identifier
Your let region:MKCoordinateRegion is a local identifier inside your delegate method:
func locationManager(_:didUpdateLocations) {...}
This is why you are getting Use of unresolved identifier. Make this identifier accessible throughout the class, the error will be gone. Like:
class SecondViewController: UIViewController, CLLocationManagerDelegate {
//Map
#IBOutlet weak var map: MKMapView!
var region = MKCoordinateRegion()
.......
.......
}
N.B: But this won't let you see anything in the map. Best way to see any output from your MapView is to put map.setRegion(region, animated: true) inside your delegate method:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.first
let span = MKCoordinateSpanMake(0.01, 0.01)
let myLocation = CLLocationCoordinate2DMake((location?.coordinate.latitude)!, (location?.coordinate.longitude)!)
region = MKCoordinateRegionMake(myLocation, span)
map.setRegion(region, animated: true)
}
Use MKCoordinateRegion instance before viewdidload method
You can follow below code for reference.
class Test: UIViewController {
var region = MKCoordinateRegion()
override func viewDidLoad() {
super.viewDidLoad()
region = MKCoordinateRegionMake(myLocation, span)
}
}
You are getting Error because
the variable region inside viewDidLoad() method do not have access of region variable inside
viewDidLoad() method
//This is where I get an error
map.setRegion(region, animated: true)**
Solution :
Make region variable global to class so that that can be accessed from anywhere you want to.
Instead of this line inside func locationManager
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation,span)
Use
self.region = MKCoordinateRegionMake(myLocation,span)
Here is complete code That you can use.
import UIKit
import MapKit
import CoreLocation
class SecondViewController: UIViewController, CLLocationManagerDelegate {
//Map
#IBOutlet weak var map: MKMapView!
//global variable
var region:MKCoordinateRegion = MKCoordinateRegion()
let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{ let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
self.region = MKCoordinateRegionMake(myLocation, span)
self.map.showsUserLocation = true
}
override func viewDidLoad()
{
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
//This is where I get an error
map.setRegion(region, animated: true)**
}
//
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
And more important if you are using simulator then you have to enable location simulation.

'MKMapView' / 'showsUserLocation = true' causing error with modal segue

I am developing a small map application which allows users to view their current location. I have the relevant code to perform this and it seems to work as expected:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {
// CLlocation
var location: CLLocation!
let locationManager = CLLocationManager()
// Map variables
var searchController:UISearchController!
var annotation:MKAnnotation!
var localSearchRequest:MKLocalSearchRequest!
var localSearch:MKLocalSearch!
var localSearchResponse:MKLocalSearchResponse!
var error:NSError!
var pointAnnotation:MKPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!
// IBOutlets
#IBOutlet weak var placesMap: MKMapView!
// Location function
func locationManager(manager: CLLocationManager, didUpdateqLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.placesMap.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Error code: " + error.localizedDescription)
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.placesMap.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
However, when I launch a modal segue to the 'About' page, from a popover (pictured below), the app crashes:
I viewed the error given to me in the terminal, this was
fatal error: unexpectedly found nil while unwrapping an Optional value
Xcode pointed me to this particular line in my viewDidLoad function:
self.placesMap.showsUserLocation = true
When I delete that particular line from my code, the location feature no longer functions, this is obvious. I have checked the outlet to the MKMapView and it seems to be correct.
I really don't know how to avoid this error, or for certainty what is causing it, so any help is appreciated.
Basically, something is making the placesMap deallocate and then viewDidLoad is being called. You might try making the placesMap optional instead of force unwrapping it, so change the ! to a ? on the property and then chain the optional into the call sites of placesMap, so self.placesMap.showsUserLocation becomes self.placesMap?.showsUserLocation and self.placesMap.setRegion(region, animated: true) becomes self.placesMap?.setRegion(region, animated: true)

SWIFT Thread 1: EXC Bad instruction XCODE IOS

I am very new to stackexchange so please let me know if i need to provide more information.
I tried to install the Corelocation and Mapkit and use them togheter. Every since i followed Vea Software Tutorial i have recived the following error:
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP,subcode=0x0)
In the compiler it says
fatal error: Unexpectedly found nil while unwrapping an Optional
Value(llDB)
The error is appering right at this line, but when i delete it, it appears at another Mapkit/Location core line. The error:
self.mapView.showsUserLocation = true
EDIT: When i remove the line above, the same error appears on
self.mapView.setRegion(region, animated: true)
I have been searching around for a while on the internet but nothing really helps me out. Thank you for your time.
If you need the whole viewcontroller code. Here it is.
import UIKit
import Parse
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
#IBOutlet var UsernameTextField: UITextField!
#IBOutlet var PasswordTF: UITextField!
#IBOutlet var EmailTF: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Location Delegate Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error:" + error.localizedDescription)
}
}
This just an hypothesis by I noticed you use
self.mapView.setRegion(region, animated: true)
in the CLLocationManager delegate and start updating before mapView is actually showing (i.e. in viewDidLoad).
Could it be that mapView is trying to update its visual states before being installed in the view hierarchy ?

Resources