Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS

Joe Hernandez
Joe Hernandez
5,699 Points

Network connectivity error or nil

I implemented location services in to the app, when I enter in coordinates the app works fine but when I use userLocation it displays NETWORK CONNECTIVTY ERROR or Nil.

Joe Hernandez
Joe Hernandez
5,699 Points

viewController.swift file

import UIKit import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate { //Location var seenError : Bool = false var locationFixAchieved : Bool = false var locationStatus : NSString = "Not Started" var locationManager: CLLocationManager! var userLocation : String! var userLatitude : Double! var userLongitude : Double!

//Current weather Outlets "Display Objects"

@IBOutlet weak var locationLabel: UILabel! @IBOutlet weak var visibilityLabel: UILabel! @IBOutlet weak var temperatureLabel: UILabel! @IBOutlet weak var iconView: UIImageView! @IBOutlet weak var currentTimeLabel: UILabel! @IBOutlet weak var humidityLabel: UILabel! @IBOutlet weak var precipitationLabel: UILabel! @IBOutlet weak var summaryLabel: UILabel! @IBOutlet weak var windSpeedLabel: UILabel! @IBOutlet weak var refreshButton: UIButton! @IBOutlet weak var refreshActivityIndicator: UIActivityIndicatorView!

//API KEY
private let apiKey = "09ca8e3e75fafbadaf4b8594dabe860e"

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

//Location Code

func initLocationManager() {
    seenError = false
    locationFixAchieved = false
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()    }

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    locationManager.stopUpdatingLocation()
    if ((error) != nil) {
        if (seenError == false) {
            seenError = true
            print(error)
        }
    }
}

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

        let pm = placemarks[0] as! CLPlacemark
        self.displayLocationInfo(pm)
    })

    if (locationFixAchieved == false) {
        locationFixAchieved = true
        var locationArray = locations as NSArray
        var locationObj = locationArray.lastObject as! CLLocation
        var coord = locationObj.coordinate
        self.userLatitude = coord.latitude
        self.userLongitude = coord.longitude

        getCurrentWeatherData()


    }
}


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 : ""
        //println(locality)
        //println(postalCode)
        //println(administrativeArea)
        //println(country)

        self.locationLabel.text = "\(locality),\(administrativeArea)"
    }
}


func locationManager(manager: CLLocationManager!,
    didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        var shouldIAllow = false

        switch status {
        case CLAuthorizationStatus.Restricted:
            locationStatus = "Restricted Access to location"
        case CLAuthorizationStatus.Denied:
            locationStatus = "User denied access to location"
        case CLAuthorizationStatus.NotDetermined:
            locationStatus = "Status not determined"
        default:
            locationStatus = "Allowed to location Access"
            shouldIAllow = true
        }
        NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
        if (shouldIAllow == true) {
            NSLog("Location to Allowed")
            // Start location services
            locationManager.startUpdatingLocation()
        } else {
            NSLog("Denied access: \(locationStatus)")
        }
}

//WEATHER
func getCurrentWeatherData() -> Void {

    userLocation = "\(userLatitude),\(userLongitude)"
                                    //Dodge Center corrdinates "44.028323,-92.858390"

    let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")

    let forecastURL = NSURL(string: "\(userLocation)", relativeToURL:baseURL)

    // creates data object; to get and save data from online
    let sharedSession = NSURLSession.sharedSession()
    let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: { (location:NSURL!, response:NSURLResponse!, error: NSError!) -> Void in

        // if everything goes alright (no errors then run code)
        if (error == nil) {

            //turn JSON dictionary to NSDictionary so it's easier to work with
            let dataObject = NSData(contentsOfURL: location)
            let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as! NSDictionary

            //bring weather dictionary from the CurrentWeather file
            let currentWeather = Current(weatherDictionary: weatherDictionary)
            println(weatherDictionary)

            //update view with current weather information
            dispatch_sync(dispatch_get_main_queue(), { () -> Void in
                self.temperatureLabel.text = "\(currentWeather.temperature)"
                self.iconView.image = currentWeather.icon!
                self.currentTimeLabel.text = "\(currentWeather.currentTime!)"
                self.humidityLabel.text = "\(currentWeather.humidity * 100)%"
                self.precipitationLabel.text = "\(currentWeather.precipProbability * 100)%"
                self.summaryLabel.text = "\(currentWeather.summary)"
                self.windSpeedLabel.text = "\(currentWeather.windSpeed) MPH"
                self.visibilityLabel.text = "\(currentWeather.visibility) Mi"

                //stop refresh animation
                self.refreshActivityIndicator.stopAnimating()
                self.refreshActivityIndicator.hidden = true
                self.refreshButton.hidden = false
            })
 }

else {

        let networkIssueController = UIAlertController(title: "Error", message: "Network Connectivity Error! Can't load data", preferredStyle: .Alert)

            //information for ok button in alertView
        let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
        networkIssueController.addAction(okButton)

            //information for cancel button in alertView
        let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
        networkIssueController.addAction(cancelButton)

        //if an error occurs show alert
        self.presentViewController(networkIssueController, animated: true, completion: nil)

        dispatch_async(dispatch_get_main_queue(), { () -> Void in
        //Stop refresh animation
        self.refreshActivityIndicator.stopAnimating()
        self.refreshActivityIndicator.hidden = true
        self.refreshButton.hidden = false

        })

        }
})

    downloadTask.resume()
}

//refresh method @IBAction func refresh() { getCurrentWeatherData() refreshButton.hidden = true refreshActivityIndicator.hidden = false refreshActivityIndicator.startAnimating() }

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

}

Joe Hernandez
Joe Hernandez
5,699 Points

currentWeather.Swift

// // CurrentWeather.swift // SPWeather // // Created by Joe Hernandez on 3/25/15. // Copyright (c) 2015 Joe Hernandez. All rights reserved. //

import Foundation import UIKit

struct Current { var currentTime: String? var temperature: Int var humidity: Double var precipProbability: Double var summary: String var icon: UIImage? var windSpeed: Int var visibility: Double

init(weatherDictionary: NSDictionary){
    //create instance of a weather dictionary called current weather
    let currentWeather = weatherDictionary["currently"] as! NSDictionary

    //connect current variable to current weather dictionary
    visibility = currentWeather["visibility"] as! Double
    windSpeed = currentWeather["windSpeed"] as! Int
    temperature = currentWeather["temperature"] as! Int
    humidity = currentWeather["humidity"] as! Double
    precipProbability = currentWeather["precipProbability"] as! Double
    summary = currentWeather["summary"] as! String
    //declare iconstring and assign to a image
    var iconString = currentWeather["icon"] as! String
    icon = weatherIconFromString(iconString)
   // initialize time to human readable time
    let currentTimeIntValue = currentWeather["time"] as! Int
    currentTime = dateStringFromUnixtime(currentTimeIntValue)

}
// convert Unix time to human readable time
func dateStringFromUnixtime(unixTime: Int) -> String {
    let timeInSeconds = NSTimeInterval(unixTime)
    let weatherDate = NSDate(timeIntervalSince1970: timeInSeconds)


    //format time to display 2:00PM type format
    let dateFormatter = NSDateFormatter()
    //formatted here
    dateFormatter.timeStyle = .ShortStyle
    // return time here in human readable time
    return dateFormatter.stringFromDate(weatherDate)

}

func weatherIconFromString(stringIcon: String) -> UIImage {
    var imageName: String

switch stringIcon {
    case "clear-day":
        imageName = "clear-day"
    case "clear-night":
        imageName = "clear-night"
    case "rain":
        imageName = "rain"
    case "snow":
        imageName = "snow"
    case "sleet":
        imageName = "sleet"
    case "wind":
        imageName = "wind"
    case "fog":
        imageName = "fog"
    case "cloudy":
        imageName = "cloudy"
    case "partly-cloudy-day":
        imageName = "partly-cloudy"
    case "partly-cloudy-night":
        imageName = "cloudy-night"
    default: imageName = "default"
    }

    var iconName = UIImage(named: imageName)
    return iconName!
}

}