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 Build a Weather App with Swift Refreshing the Data The End

Aniket Kumar
Aniket Kumar
3,266 Points

How am I suppose to implement CLLocationManager for updating the location?

I have been working on this for a while and can't seem to figure it out. I have looked at the documentation and added the necessary details to the info.plist. My code does not seem to get to the function that is responsible for retrieving the updated location. Here is my code:

let locationManager: CLLocationManager = CLLocationManager() var updatedLocationsArray = AnyObject

override func viewDidLoad() { super.viewDidLoad() self.locationManager.requestWhenInUseAuthorization() if (CLLocationManager.locationServicesEnabled()){ println("Called!") locationManager.delegate = self locationManager.distanceFilter = kCLDistanceFilterNone locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.startUpdatingLocation() println("Update started")} locationManagerFunc(locationManager, didUpdateLocations: updatedLocationsArray) }

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

    println("Func has been summoned")

    var locationsArray = locations as NSArray
    var locationObject = locationsArray.lastObject as? CLLocation
    if (locationObject != nil) {
    var newCoordinatesLat = locationObject?.coordinate.latitude
        var newCoordinateLong = locationObject?.coordinate.longitude

    println("Begin the func!")
        println("\(newCoordinateLong)")
        retrieveWeatherForecast(newCoordinatesLat!, coordinateInputLong: newCoordinateLong!)
    }}

My output prints up to "Func has been summoned". There seems to be a problem with my updatedLocationsArray, or with the second parameter of the locationManagerFunc.

Any help would be appreciated! I have looked at stack overflow.

2 Answers

oivindberg
seal-mask
PLUS
.a{fill-rule:evenodd;}techdegree seal-36
oivindberg
Full Stack JavaScript Techdegree Graduate 43,923 Points

Sorry for not answering before!

Thanks for reaching out to me for an answer. However, I am only starting out with IOS development and dont know the anser to your question.

Again, sorry for taking so long.

Keli'i Martin
Keli'i Martin
8,227 Points

I just happened upon this question and noticed that you never got an answer. I don't know if you have already solved your issues with this, but I thought I might be of some assistance. First, I'm re-pasting your code so I can reformat it for ease of reading.

let locationManager: CLLocationManager = CLLocationManager() 
var updatedLocationsArray = AnyObject

override func viewDidLoad() { 
    super.viewDidLoad()
    self.locationManager.requestWhenInUseAuthorization()
    if (CLLocationManager.locationServicesEnabled()){ 
        println("Called!")
        locationManager.delegate = self
        locationManager.distanceFilter = kCLDistanceFilterNone
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
        println("Update started")
    }

    locationManagerFunc(locationManager, didUpdateLocations: updatedLocationsArray)
}

func locationManagerFunc(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    println("Func has been summoned")

    var locationsArray = locations as NSArray
    var locationObject = locationsArray.lastObject as? CLLocation
    if (locationObject != nil) {
        var newCoordinatesLat = locationObject?.coordinate.latitude
        var newCoordinateLong = locationObject?.coordinate.longitude

        println("Begin the func!")
        println("\(newCoordinateLong)")
        retrieveWeatherForecast(newCoordinatesLat!, coordinateInputLong: newCoordinateLong!)
    }
}

I'm assuming you've already done the prerequisite steps to begin using CoreLocation (importing the framework, setting the project up properly, implementing the CLLocationManagerDelegate protocol, etc). Right off the bat, your updatedLocationsArray is not being initialized as an array at all but just as a single AnyObject object. You should have var updatedLocationsArray = [AnyObject] to declare that as an array. But honestly, you don't even need to make that a property of the ViewController at all.

You've got the proper setup in your viewDidLoad() method, which is good. But you've got this custom locationManagerFunc() method that you don't need. When you implemented the CLLocationManagerDelegate protocol, there is a function defined in the protocol called locationManager:didUpdateLocations: that you just need to implement in your code. The proper function declaration looks like this:

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

CLLocationManager has a useful property called .location which is simply the most recently retrieved user location. There is a chance that this location data might be old, but for an app like this, it should be fine. Otherwise, you can just access the locations array and get the latest location from there as well. You also might want to call locationManager.stopUpdatingLocation() in this method, since you don't need to constantly update the location once you have it to pass on to your retrieveWeatherForecast() method. If you do that, you'll want to make sure that in your refreshWeather() method, you once again call locationManager.startUpdatingLocation(), otherwise you will not get the most recent location.

That should be enough to get your location stuff working. Your location label will not match the location you get though, since it is hardcoded. If you wanted to get the actual location name, you can use the CLGeocoder().reverseGeocodeLocation(_ location: CLLocation, completionHandler completionHandler: CLGeocodeCompletionHandler) method to get that information.

Anyway, I hope this was of some help.