Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Scott Brown
Scott Brown
4,406 Points

Retrieving user postal code for use in Swift Project

Hello,

I am having problems putting user postal code as a variable I can return for use throughout my project. I normally sendup with a situation where I can get it to print or I can put it into a text field but if I try to use the variable it is normally difficult because it ends up trapped in a closure type situation. I am going to post the two methods I have been using which only works up to a point.

//Method 1 :

import UIKit import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

@IBOutlet var localityTxtField: UITextField!
@IBOutlet var postalCodeTxtField: UITextField!
@IBOutlet var aAreaTxtField: UITextField!
@IBOutlet var countryTxtField: UITextField!

let locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

@IBAction func findMyLocation(_ sender: AnyObject) {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in

        if (error != nil) {
            print("Reverse geocoder failed with error" + (error?.localizedDescription)!)
            return
        }

        if (placemarks?.count)! > 0 {
            let pm = placemarks?[0]
            self.displayLocationInfo(pm)
            print (self.displayLocationInfo(pm))
        } else {
            print("Problem with the data received from geocoder")
        }
    })
}

func displayLocationInfo(_ placemark: CLPlacemark?) {
    if let containsPlacemark = placemark {
      //stop updating location to save battery life
        locationManager.stopUpdatingLocation()
        //let locality = (containsPlacemark.locality != nil) ? containsPlacemark.locality : ""
        let postalCode = (containsPlacemark.postalCode != nil) ? containsPlacemark.postalCode : ""
        //let administrativeArea = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
       // let country = (containsPlacemark.country != nil) ? containsPlacemark.country : ""

        /*
        localityTxtField.text = locality
        postalCodeTxtField.text = postalCode
        aAreaTxtField.text = administrativeArea
        countryTxtField.text = country

*/

}


func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
      print("Error while updating location " + error.localizedDescription)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

// Method 2:

func doSomething() {

   // func yup() -> (Int) {
    self.getAddress() { (address) in

        //(address)

       print(address)
        //step 4, finishing the execution
    }

}




func getAddress(handler: @escaping (String) -> ())
{

    self.locationManager.requestAlwaysAuthorization()
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    locationManager.requestWhenInUseAuthorization()
    //locationManager.startUpdatingLocation()
   // let locationManager = CLLocationManager()

    var userLatitude:CLLocationDegrees! //= 0
    var userLongitude:CLLocationDegrees!// = 0

        //if self.locationManager != nil {

            //assign your loaction values here
            userLatitude = locationManager.location?.coordinate.latitude

            userLongitude = locationManager.location?.coordinate.latitude

       // } else {
            //print("locationManager.location is nil")
        //}

    userLatitude = locationManager.location?.coordinate.latitude

    userLongitude = locationManager.location?.coordinate.latitude


    Latitude_Double = Double(userLatitude)
    Longitude_Double = Double(userLongitude)


    var address: String = ""
    let geoCoder = CLGeocoder()
    let location = CLLocation(latitude: Latitude_Double, longitude: Longitude_Double)
    //selectedLat and selectedLon are double values set by the app in a previous process

    geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in

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

        // Address dictionary
        //print(placeMark.addressDictionary ?? "")
      /*
        // Location name
        if let locationName = placeMark?.addressDictionary?["Name"] as? String {
            address += locationName + ", "
        }

        // Street address
        if let street = placeMark?.addressDictionary?["Thoroughfare"] as? String {
            address += street + ", "
        }
        // City
        if let city = placeMark?.addressDictionary?["City"] as? String {
            address += city + ", "
        }
       */

        // Zip code
        if let zip = placeMark?.addressDictionary?["ZIP"] as? String {
            address += zip + ", "
        }

        /*

        // Country
        if let country = placeMark?.addressDictionary?["Country"] as? String {
            address += country
        }
       */

        // Passing address back
        handler(address)
    })
    }
}

In Method 1 I think if we could retrieve self.displayLocationInfo(pm) that would be great and I think in Method 2 if we could get address to be returned from func doSomething() it can work. Quick note I am not that good with closures and I recognize I don't have fun doSomething() as a return function because I am not entirely sure how to do it in this context. I know this may be a lot to parse through but any help would be appreciated. Thanks in advance.