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

Stormy with CoreLocation correct values show only after hitting refresh Button.

Hi,

I am currently updating the Stormy App to work with GPS. Therefore I added the CoreLocation Framework and created a new Controller. And so far it works - I get the Long, Lat and Location from the user BUT it only updates the Labels when I hit the refresh button.

Here is my ViewController(only the important code):

var coreLocation: CoreLocationController = CoreLocationController()

override func viewDidLoad() {
        super.viewDidLoad()
}

func retrieveWeatherForecast() {
        let forecastService = ForecastService(APIKey: forecastAPIKey)
        let userLatitude = coreLocation.userLatitude
        let userLongitude = coreLocation.userLongitude
        let userLocation = coreLocation.userLocation
        forecastService.getForecast(userLatitude, long: userLongitude) {
            (let currently) in
            if let currentWeather = currently {
                dispatch_async(dispatch_get_main_queue()) {
                    // Running now in main thread
                    if let temperature = currentWeather.temperature_celsius {
                        self.currentTemperatureLabel?.text = "\(temperature)°"
                    }

                    if let humidity = currentWeather.humidity {
                        self.currentHumidityLabel?.text = "\(humidity)%"
                    }

                    if let precipitation = currentWeather.precipProbability {
                        self.currentPrecipitationLabel?.text = "\(precipitation)%"
                    }

                    if let icon = currentWeather.icon {
                        self.currentWeatherIcon?.image = icon
                    }

                    if let summary = currentWeather.summary {
                        self.currentWeatherSummary?.text = summary
                    }
                    self.currentLocation?.text = userLocation
                    self.toggleRefreshAnimation(false)
                }
            }
        }

    }


@IBAction func refreshWeather() {
    toggleRefreshAnimation(true)
    retrieveWeatherForecast()
}

and my CoreLoactionController

class CoreLocationController : NSObject, CLLocationManagerDelegate {

    var locationManager:CLLocationManager = CLLocationManager()

    var userLongitude: Double
    var userLatitude: Double
    var userLocation: String

    override init() {
        userLatitude = (locationManager.location?.coordinate.latitude)!
        userLongitude = (locationManager.location?.coordinate.longitude)!
        userLocation = ""
        super.init()
        self.locationManager.delegate = self
        self.locationManager.distanceFilter  = 3000                         // Must move at least 3km
        self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer // Accurate within a kilometer
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
    }

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        print("didChangeAuthorizationStatus")

        switch status {
        case .NotDetermined:
            print(".NotDetermined")
            break

        case .AuthorizedWhenInUse:
            print(".Authorized")
            self.locationManager.startUpdatingLocation()
            break

        case .Denied:
            print(".Denied")
            break

        default:
            print("Unhandled authorization status")
            break

        }
    }

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

        let location = locations.last as! CLLocation

        print("didUpdateLocations:  \(location.coordinate.latitude), \(location.coordinate.longitude)")

        userLatitude = location.coordinate.latitude
        userLongitude = location.coordinate.longitude

        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, e) -> Void in
            if let error = e {
                print("Error:  \(error.localizedDescription)")
            } else {
                let placemark = placemarks!.last as CLPlacemark?

                let userInfo = [
                    "city":     placemark!.locality,
                    "state":    placemark!.administrativeArea,
                    "country":  placemark!.country
                ]

                print("Location:  \(userInfo)")
                self.userLocation = userInfo["city"]!
            }
            print("test \(self.userLocation)")
        })
        self.locationManager.stopUpdatingLocation()
    }
}

I've tried different things. To start updating the location in the viewDidLoad() function and calling retrieveWeatherForecast() afterwards. I also tried calling retrieveWeatherForecast() in my "func locationManager(manager: CLLocationManager, didUpdateLocations locations: [AnyObject])" function after the city is encoded. And it doesn't work which I don't understand because all the (Refresh-Button) refreshWeather() function is doing, is calling retrieveWeatherForecast(). And no matter where I place the retrieveWeatherForecast() function, it never display the current values or city. I always have to hit the refresh button to display the correct values and city.

So, can someone explain why this is happening? And if someone have a solution for my problem I would glad to hear it. Thank you very much in advance! Maybe Pasan Premaratne can help me?

-David