0

I've used this code for my App. Its works great but sometime crashes, after +/- 50 secondes of tracking my route. I know it has something to do with the optionals "?", but I can't get it to work.

I get the following message:

fatal error: unexpectedly found nil while unwrapping an Optional

Part where the code breaks:

 if let locationName = placeMark.addressDictionary?["Name"] as? NSString
      {
         print(locationName)
         self.locationName = locationName as String
      }   

Full locationManager code:

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

    for location in locations as [CLLocation] {
        let howRecent = location.timestamp.timeIntervalSinceNow

        //start motion tracker
        motionTracker()

        //location name tracker
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        let latitude: CLLocationDegrees = locValue.latitude
        let longitude: CLLocationDegrees = locValue.longitude
        let geoCoder = CLGeocoder()
        let location = CLLocation(latitude: latitude, longitude: longitude)
        geoCoder.reverseGeocodeLocation(location)
            {
                (placemarks, error) -> Void in

                let placeArray = placemarks as [CLPlacemark]!

                // Place details
                var placeMark: CLPlacemark!
                placeMark = placeArray?[0]

                // Address dictionary
                print(placeMark.addressDictionary)

                // Location name
                if let locationName = placeMark.addressDictionary?["Name"] as? NSString
                {
                    print(locationName)
                    self.locationName = locationName as String
                }

                // Street address
                if let street = placeMark.addressDictionary?["Thoroughfare"] as? NSString
                {
                    //print(street)
                    self.locationStreet = street as String                 
                }

                // City
                if let city = placeMark.addressDictionary?["City"] as? NSString
                {
                    self.locationCity = city as String
                    //print(city)
                }

                // Zip code
                if let zip = placeMark.addressDictionary?["ZIP"] as? NSString
                {
                    //print(zip)
                }

                // Country
                if let country = placeMark.addressDictionary?["Country"] as? NSString
                {
                    //print(country)
                }
        }
Community
  • 1
  • 1
Lengo
  • 342
  • 7
  • 14
  • Immediately before that line, you `print(placeMark.addressDictionary)`. Just before it crashes, what does that print? – jbg Jan 02 '16 at 10:35
  • @JasperBryant-Greene: it prints out: `Optional([SubLocality: Millbrae Meadows, SubAdministrativeArea: San Mateo, State: CA, Street: I-280 N, CountryCode: US, ZIP: 94030, Thoroughfare: I-280 N, Name: I-280 N, Country: United States, FormattedAddressLines: ( "I-280 N", "Half Moon Bay, CA 94030", "United States" ), City: Half Moon Bay]) I-280 N empty fatal error: unexpectedly found nil while unwrapping an Optional` the empty is the motiontracker – Lengo Jan 02 '16 at 10:39
  • The print line is crashing the next time around the loop, because `placeMark` is `nil` so `print(placeMark.addressDictionary)` fails. Google doesn’t have a reverse geocode for that location and is returning an empty array. See my answer below. – jbg Jan 02 '16 at 10:42

1 Answers1

2

I suspect you’re hitting a case where Google doesn’t have a reverse geocode result for your location and is returning an empty array.

Instead of:

let placeArray = placemarks as [CLPlacemark]!
var placemark: CLPlacemark!
placemark = placeArray?[0]

… which assumes that there will be an array and it will always contain at least one element, use:

if let placemark = placemarks?.first {
    // Rest of your code
}
jbg
  • 4,903
  • 1
  • 27
  • 30
  • I updated the answer to handle the case that the geocoder doesn’t provide an array at all – it’s documented that `placemarks` can be nil if an error occurred: https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLGeocoder_class/#//apple_ref/doc/c_ref/CLGeocodeCompletionHandler – jbg Jan 02 '16 at 10:52