1

In using CLGeocoder I get a crash (EXC_BAD_ACCESS) right after the let placemark ... in the closure success part which I don't understand. I am testing and may have made tried to access the server many times. Or do I need to make the call in a background thread?

import UIKit
import CoreLocation

class ViewController: UIViewController {

var destinationPlacemark = CLPlacemark()

override func viewDidLoad() {
    super.viewDidLoad()
    forwardGeocoding(address: "Infinite Loop, Cupertino, CA 95014")
}

func forwardGeocoding(address: String) {
    CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
        if error != nil {
            print(error ?? "Error in plscement conversion")
            return
        }
        if (placemarks?.count)! > 0 {
            let placemark = placemarks?[0]
            let location = self.destinationPlacemark.location
            let coordinate = location?.coordinate
            print("Latitude: \(coordinate!.latitude), Longitude: \(coordinate!.longitude)")

            self.destinationPlacemark = placemark!
        }
    })
}

}
mfaani
  • 33,269
  • 19
  • 164
  • 293
Syed Tariq
  • 2,878
  • 3
  • 27
  • 37
  • FYI I just asked this question: https://stackoverflow.com/questions/41840082/why-do-i-get-exc-bad-access-right-after-instantiation – mfaani Jan 24 '17 at 22:25

1 Answers1

0

*Updated with cause *

You had quite a few things here, so I will try to step through the changes I made to fix it:

First, why it crashes:

You create your destinationPlacemark with the following command:

var destinationPlacemark = CLPlacemark()

So when this runs:

let location = self.destinationPlacemark.location

It is running against an empty placemark that contains no location data. By pulling the location from the retrieved placemark created in the guard statement, this issue is avoided.

Next, the working code:

import UIKit
import CoreLocation

class ViewController: UIViewController {

    var destinationPlacemark: CLPlacemark?

    override func viewDidLoad() {
        super.viewDidLoad()
        forwardGeocoding(address: "1 Infinite Loop, Cupertino, CA 95014")
    }

    func forwardGeocoding(address: String) {
        CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
            if error != nil {
                print(error ?? "Error in pla conversion")
                return
            }

            guard let placemark = placemarks?.first, let coordinate = placemark.location?.coordinate else { return }
            print("Latitude: \(coordinate.latitude), Longitude: \(coordinate.longitude)")

            self.destinationPlacemark = placemark
        })
    }

}

Which produces:

Latitude: 37.3316941, Longitude: -122.030127
  1. You do not set up the variable for destinationPlacemark properly, see the above for a proper setup
  2. Your address for Apple is wrong, I added a 1 to the front, though you still get a value
  3. You are forcing too many items, which leads to crashes as you saw. I replaced your forced casts with a guard statement to prevent those
  4. I de-clutttered some variables in your success section to streamline the code
CodeBender
  • 35,668
  • 12
  • 125
  • 132
  • your answer works, but you didn't explain the why. He did initialize `destinationPlacemark` so what's the reason for that to create an error? I mean just because your safely unwrapping something, it will then not crash, but still you may have a nil for something... – mfaani Jan 24 '17 at 20:57
  • He had the wrong address for Apple (Step 2) but I will clarify – CodeBender Jan 24 '17 at 20:58
  • From the OP's code, I added "1" to his address and it *still* failed. – mfaani Jan 24 '17 at 21:20
  • @Honey Updated with explanation of cause – CodeBender Jan 24 '17 at 21:57
  • Thank you. I learnt a lesson for not using the guard statement around the various places I could be getting an illegal response. – Syed Tariq Jan 24 '17 at 22:01
  • @SyedTariq No problem, guard is something to use liberally IMO - even if it's just to avoid using ? all over the place – CodeBender Jan 24 '17 at 22:03
  • The main reason was that I was trying to use `let location = self.destinationPlacemark.location' in which the destinationPlacemark was initially set to nil. I got confused when I got the crash message. – Syed Tariq Jan 24 '17 at 22:08