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 trialagreatdaytocode
24,757 PointsStormy Remix!
Hello!
So I figured out how to grab the user location and implement it into the Stormy App. The problem is that it's not working on launch. The user must refresh the data before it works.
Here is the code.
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
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!
@IBOutlet weak var iconView: UIImageView!
@IBOutlet weak var currentTimeLabel: UILabel!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var precipitationLabel: UILabel!
@IBOutlet weak var summaryLabel: UILabel!
@IBOutlet weak var refreshButton: UIButton!
@IBOutlet weak var refreshActivityIndicator: UIActivityIndicatorView!
private let apiKey = "your API KEY :)"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initLocationManager()
getCurrentWeatherData()
}
// This is the 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]!) {
if (locationFixAchieved == false) {
locationFixAchieved = true
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
var coord = locationObj.coordinate
//println(coord.latitude)
//println(coord.longitude)
self.userLatitude = coord.latitude
self.userLongitude = coord.longitude
println(userLocation)
}
}
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)"
let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
let forecastURL = NSURL(string: "\(userLocation)", relativeToURL:baseURL)
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
if (error == nil) {
let dataObject = NSData(contentsOfURL: location)
let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject, options: nil, error: nil) as NSDictionary
let currentWeather = Current(weatherDictionary:weatherDictionary)
//Test Connection and API with the folllowing
//println(currentWeather.temperature)
//println(currentWeather.currentTime!)
//println(weatherDictionary)
//Main dispatch AKA Party Time!
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.temperatureLabel.text = "\(currentWeather.temperature)"
self.iconView.image = currentWeather.icon
self.currentTimeLabel.text = "At \(currentWeather.currentTime!) it is"
self.humidityLabel.text = "\(currentWeather.humidity)"
self.precipitationLabel.text = "\(currentWeather.precipProbability)"
self.summaryLabel.text = "\(currentWeather.summary)"
//Stop refresh
self.refreshActivityIndicator.stopAnimating()
self.refreshActivityIndicator.hidden = true
self.refreshButton.hidden = false
})
} else {
let networkIssueController = UIAlertController(title: "Error", message: "Unable to load data. Connectivity error!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
networkIssueController.addAction(okButton)
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
networkIssueController.addAction(cancelButton)
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()
}
@IBAction func refresh() {
refreshButton.hidden = true
refreshActivityIndicator.hidden = false
refreshActivityIndicator.startAnimating()
getCurrentWeatherData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Any ideas on how I could fix this?
Pasan Premaratne
Treehouse TeacherDo you mean that you don't get the dialog requesting access to location right when the app starts?
agreatdaytocode
24,757 PointsPasan, I get the dialog, but the user location is not updated until after I hit the refresh button. The first thing that pop's up is the message ""Error unable to load data. Connectivity error!"
10 Answers
Dino Paškvan
Courses Plus Student 44,108 PointsThis kind of location manager configuration is overkill for a weather app:
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
A navigation app or an app providing users with info about landmarks in their vicinity would use kCLLocationAccuracyBest
. A weather app can make do with kCLLocationAccuracyThreeKilometers
.
Also, monitoring for all location changes instead of significant ones will burn through the device battery fairly quickly (especially with the default value of the distanceFilter
property).
Once you only monitor for significant changes, you can have the locationManager(_:didUpdateLocations:)
method call the function that updates the weather info, and it won't be triggered every second, but rather when users make a significant location change (when they change cell towers). Users won't need to refresh manually, the location manager delegate function will do it for them once it gets a fix on the current location.
agreatdaytocode
24,757 PointsGood to know thanks.
agreatdaytocode
24,757 Points<UILabel: 0x15e6139c0; frame = (60 213; 200.5 142); text = '120'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17808b5e0>>
2014-10-10 17:17:47.650 Stormy[2183:795348] Location to Allowed
nil,nil
any idea on how to make sure the location gets pasted to the userLocation before the locationManager launches?
agreatdaytocode
24,757 PointsNever mind I figured it out : ) I added the getCurrentWeatherData() to the locationManger func and it works like a charm now.
agreatdaytocode
24,757 Pointsimport UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
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
@IBOutlet weak var iconView: UIImageView!
@IBOutlet weak var currentTimeLabel: UILabel!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var precipitationLabel: UILabel!
@IBOutlet weak var summaryLabel: UILabel!
@IBOutlet weak var refreshButton: UIButton!
@IBOutlet weak var refreshActivityIndicator: UIActivityIndicatorView!
//Daily Weather outlets
@IBOutlet weak var myTestLabel: UILabel!
private let apiKey = "Your API KEY"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initLocationManager()
}
//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]!) {
if (locationFixAchieved == false) {
locationFixAchieved = true
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
var coord = locationObj.coordinate
//println(coord.latitude)
//println(coord.longitude)
self.userLatitude = coord.latitude
self.userLongitude = coord.longitude
println(userLocation)
getCurrentWeatherData()
}
}
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)"
let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
let forecastURL = NSURL(string: "\(userLocation)", relativeToURL:baseURL)
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
if (error == nil) {
let dataObject = NSData(contentsOfURL: location)
let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject, options: nil, error: nil) as NSDictionary
let currentWeather = Current(weatherDictionary:weatherDictionary)
//Test Connection and API with the folllowing
//println(currentWeather.temperature)
//println(currentWeather.currentTime!)
//println(weatherDictionary)
//Main dispatch AKA Party Time!
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.temperatureLabel.text = "\(currentWeather.temperature)"
self.iconView.image = currentWeather.icon
self.currentTimeLabel.text = "At \(currentWeather.currentTime!) it is"
self.humidityLabel.text = "\(currentWeather.humidity)"
self.precipitationLabel.text = "\(currentWeather.precipProbability)"
self.summaryLabel.text = "\(currentWeather.summary)"
self.myTestLabel.text = "\(myNewTemp)"
//Stop refresh
self.refreshActivityIndicator.stopAnimating()
self.refreshActivityIndicator.hidden = true
self.refreshButton.hidden = false
})
} else {
let networkIssueController = UIAlertController(title: "Error", message: "Unable to load data. Connectivity error!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
networkIssueController.addAction(okButton)
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
networkIssueController.addAction(cancelButton)
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()
}
@IBAction func refresh() {
refreshButton.hidden = true
refreshActivityIndicator.hidden = false
refreshActivityIndicator.startAnimating()
getCurrentWeatherData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Try that, and add "NSLocationAlwaysUsageDescription" to your info.plist :)
agreatdaytocode
24,757 PointsOh man its been weeks now. I have updated my code many times. It now looks like this Project RainMan and This
Are you having issues with the code at all?
Bradley Maskell
8,858 PointsYes. I'm not sure where you were using (myNewTemp) and what label you were using @IBOutlet weak var myTestLabel: UILabel! with.
Bradley Maskell
8,858 PointsI updated my code with comments to show where I am confused.
Your app looks great by the way.
agreatdaytocode
24,757 Points@IBOutlet weak var myTestLabel: UILabel!
I was using this to test out the daily weather info that I wanted to bring in same for the mynewTemp. It was test code for the high and low for the current day.
If you remove both you should be ok.
Bradley Maskell
8,858 PointsI keep getting a denied access: Status not determined warning. I'm testing on an actual device. In settings/general/privacy/location/story I set the location to allow always. However every time I rerun the app it doesn't remember this setting. Any advice?
Also, thanks for clearing up the above problem!
agreatdaytocode
24,757 PointsTry deleting the app on the phone. Then clean the project before reinstalling it.
Bradley Maskell
8,858 PointsThanks. Just did everything as instructed but it still does the same thing.
agreatdaytocode
24,757 PointsHmm that is odd. Ill search around and see if I can find anything on the web about it.
Bradley Maskell
8,858 PointsThanks. I checked Apple Docs but it wasn't very clear about it.
mamat golo
Courses Plus Student 3,755 PointsI got the same problem like you Aaron Ackerman , please help me how did you solve the problem? or if you don't mind please paste the code for the solution that you did. I tried to added getCurrentWeatherData but still have no luck. :(
Bradan Jackson
20,558 PointsI already have this much, but how do you get it to find the city name, based on coordinates, for the label?
agreatdaytocode
24,757 PointsHi Bradan, check out my post here
Bradan Jackson
20,558 PointsHello Aaron, I copied and pasted that code into a blank project, added the key to the .plist file (and imported the CoreLocation framework), and I don't get any errors, but nothing comes up in the console when I run it.
Am I doing something wrong?
agreatdaytocode
24,757 PointsCan you post your code?
Bradley Maskell
8,858 PointsAaron Ackerman , Where are you getting (myNewTemp) from?
Here is my code from the View Controller...
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
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
@IBOutlet weak var iconView: UIImageView!
@IBOutlet weak var currentTimeLabel: UILabel!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var precipitationLabel: UILabel!
@IBOutlet weak var summaryLabel: UILabel!
@IBOutlet weak var refreshButton: UIButton!
@IBOutlet weak var refreshActivityIndicator: UIActivityIndicatorView!
//Daily Weather outlets
@IBOutlet weak var myTestLabel: UILabel! // not sure which label to connect this to
private let apiKey = "PRIVATE"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//refreshActivityIndicator.hidden = true
//getCurrentWeatherData()
initLocationManager()
}
//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]!) {
if (locationFixAchieved == false) {
locationFixAchieved = true
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
var coord = locationObj.coordinate
//println(coord.latitude)
//println(coord.longitude)
self.userLatitude = coord.latitude
self.userLongitude = coord.longitude
println(userLocation)
getCurrentWeatherData()
}
}
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)"
let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
let forecastURL = NSURL(string: "\(userLocation)", relativeToURL: baseURL)
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
if (error == nil){
let dataObject = NSData(contentsOfURL: location)
let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary
let currentWeather = Current(weatherDictionary: weatherDictionary)
//Test Connection and API with the folllowing
println(currentWeather.temperature)
println(currentWeather.currentTime!)
println(weatherDictionary)
//Main dispatch
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.temperatureLabel.text = "\(currentWeather.temperature)"
self.iconView.image = currentWeather.icon!
self.currentTimeLabel.text = "At \(currentWeather.currentTime!) it is"
self.humidityLabel.text = "\(currentWeather.humidity)"
self.precipitationLabel.text = "\(currentWeather.precipProbability)"
self.summaryLabel.text = "\(currentWeather.summary)"
self.myTestLabel.text = "\(myNewTemp)" // error here
// Stop refresh animation
self.refreshActivityIndicator.stopAnimating()
self.refreshActivityIndicator.hidden = true
self.refreshButton.hidden = false
})
} else {
let networkIssueController = UIAlertController(title: "Error", message: "Unable to load data. Connectivity error!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
networkIssueController.addAction(okButton)
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
networkIssueController.addAction(cancelButton)
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()
}
@IBAction func refresh() {
refreshButton.hidden = true
refreshActivityIndicator.hidden = false
refreshActivityIndicator.startAnimating()
getCurrentWeatherData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Also, what label are you connecting "@IBOutlet weak var myTestLabel: UILabel!" to? Thanks!
Joe Hernandez
5,699 PointsFor label I get coordinates, how can I get a string of a name of a town they're in?
agreatdaytocode
24,757 PointsHi Joe,
You can bring this in via locality and administrative Area.
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.userLocationLabel.text = "\(locality), \(administrativeArea)"
}
}
Joe Hernandez
5,699 Pointscan I put it anywhere? it doesn't update label for me
agreatdaytocode
24,757 PointsYou should have an update function. Let me give you a copy of my file.
agreatdaytocode
24,757 PointsHere is what the file looks like
//: Playground - noun: a place where people can play
//
// ViewController.swift
// Stormy
//
// Created by Mav3r1ck on 9/28/14.
// Copyright (c) 2014 Mav3r1ck. All rights reserved.
//
import UIKit
import AVFoundation
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
let swipeRec = UISwipeGestureRecognizer()
//Current Weather outlets
@IBOutlet weak var windBag: UIImageView!
@IBOutlet weak var umbrella: UIImageView!
@IBOutlet weak var rainDrop: UIImageView!
@IBOutlet weak var userLocationLabel: UILabel!
@IBOutlet weak var iconView: UIImageView!
//@IBOutlet weak var currentTimeLabel: UILabel!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var precipitationLabel: UILabel!
@IBOutlet weak var windSpeedLabel: UILabel!
@IBOutlet weak var summaryLabel: UILabel!
//@IBOutlet weak var refreshActivityIndicator: UIActivityIndicatorView!
@IBOutlet weak var degreeButton: UIButton!
@IBOutlet weak var swipeView: UIView!
@IBOutlet weak var heatIndex: UIImageView!
@IBOutlet weak var dayZeroTemperatureLowLabel: UILabel!
@IBOutlet weak var dayZeroTemperatureHighLabel: UILabel!
@IBOutlet weak var windUILabel: UILabel!
@IBOutlet weak var rainUILabel: UILabel!
@IBOutlet weak var humidityUILabel: UILabel!
//Daily Weather outlets
@IBOutlet weak var dayZeroTemperatureLow: UILabel!
@IBOutlet weak var dayZeroTemperatureHigh: UILabel!
@IBOutlet weak var dayOneWeekDayLabel: UILabel!
@IBOutlet weak var dayOneHighLow: UILabel!
@IBOutlet weak var dayOneImage: UIImageView!
@IBOutlet weak var dayTwoWeekDayLabel: UILabel!
@IBOutlet weak var dayTwoHighLow: UILabel!
@IBOutlet weak var dayTwoImage: UIImageView!
@IBOutlet weak var dayThreeWeekDayLabel: UILabel!
@IBOutlet weak var dayThreeHighLow: UILabel!
@IBOutlet weak var dayThreeImage: UIImageView!
@IBOutlet weak var dayFourWeekDayLabel: UILabel!
@IBOutlet weak var dayFourHighLow: UILabel!
@IBOutlet weak var dayFourImage: UIImageView!
@IBOutlet weak var dayFiveWeekDayLabel: UILabel!
@IBOutlet weak var dayFiveHighLow: UILabel!
@IBOutlet weak var dayFiveImage: UIImageView!
@IBOutlet weak var daySixWeekDayLabel: UILabel!
@IBOutlet weak var daySixHighLow: UILabel!
@IBOutlet weak var daySixImage: UIImageView!
//Alerts
@IBOutlet weak var wAlerts: UILabel!
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!
private let apiKey = "yourKEY"
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
swipeRec.addTarget(self, action: "swipedView")
swipeRec.direction = UISwipeGestureRecognizerDirection.Down
swipeView.addGestureRecognizer(swipeRec)
refresh()
//PushNotifications
}
func swipedView(){
self.swooshsound()
refresh()
}
//LOCATION LOCATION LOCATION
func initLocationManager() {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
}
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.userLocationLabel.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)"
let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
let forecastURL = NSURL(string: "\(userLocation)", relativeToURL:baseURL)
//39.1267,-77.714 Purcellville VA (EAST COAST USA)
//72.371224,-41.382676 GreenLand (Cold Place!)
//\(userLocation) (YOUR LOCATION!)
//println(userLocation)
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
if (error == nil) {
let dataObject = NSData(contentsOfURL: location)
let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as! NSDictionary
let currentWeather = Current(weatherDictionary: weatherDictionary)
let weeklyWeather = Weekly(weatherDictionary: weatherDictionary)
var alertWeather = WeatherAlerts(weatherDictionary: weatherDictionary)
//Test Connection and API with the folllowing
//println(currentWeather.temperature)
//println(currentWeather.currentTime!)
println(weatherDictionary)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//Current outlook
self.temperatureLabel.text = "\(currentWeather.temperature)"
self.iconView.image = currentWeather.icon
//self.currentTimeLabel.text = "\(currentWeather.currentTime!)"
self.humidityLabel.text = "\(currentWeather.humidity)"
self.precipitationLabel.text = "\(currentWeather.precipProbability)"
self.summaryLabel.text = "\(currentWeather.summary)"
self.windSpeedLabel.text = "\(currentWeather.windSpeed)"
self.dayZeroTemperatureHigh.text = "\(weeklyWeather.dayZeroTemperatureMax)"
self.dayZeroTemperatureLow.text = "\(weeklyWeather.dayZeroTemperatureMin)"
// Notification Statements
if currentWeather.precipProbability == 1.0 {
var localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Project RainMan"
localNotification.alertBody = "Don't forget your umbrella today!"
localNotification.fireDate = NSDate(timeIntervalSinceNow: 8)
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
if currentWeather.windSpeed > 38.0 {
var localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Project RainMan"
localNotification.alertBody = "It's going to be windy today!"
localNotification.fireDate = NSDate(timeIntervalSinceNow: 8)
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
if weeklyWeather.dayZeroTemperatureMax > 90 {
var localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Project RainMan"
localNotification.alertBody = "It's going to be Hot today!"
localNotification.fireDate = NSDate(timeIntervalSinceNow: 8)
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
//HEAT INDEX
if currentWeather.temperature < 60 {
self.heatIndex.image = UIImage(named: "heatindexWinter")
self.dayZeroTemperatureLow.textColor = UIColor(red: 0/255.0, green: 121/255.0, blue: 255/255.0, alpha: 1.0)
self.dayZeroTemperatureHigh.textColor = UIColor(red: 245/255.0, green: 6/255.0, blue: 93/255.0, alpha: 1.0)
} else {
self.heatIndex.image = UIImage(named:"heatindex")
}
//7 day out look
self.dayOneWeekDayLabel.text = "\(weeklyWeather.dayOneTime!)"
self.dayOneHighLow.text = "\(weeklyWeather.dayOneTemperatureMin)°/ \(weeklyWeather.dayOneTemperatureMax)°"
self.dayOneImage.image = weeklyWeather.dayOneIcon
self.dayTwoWeekDayLabel.text = "\(weeklyWeather.dayTwoTime!)"
self.dayTwoHighLow.text = "\(weeklyWeather.dayTwoTemperatureMin)°/ \(weeklyWeather.dayTwoTemperatureMax)°"
self.dayTwoImage.image = weeklyWeather.dayTwoIcon
self.dayThreeWeekDayLabel.text = "\(weeklyWeather.dayThreeTime!)"
self.dayThreeHighLow.text = "\(weeklyWeather.dayThreeTemperatureMin)°/ \(weeklyWeather.dayThreeTemperatureMax)°"
self.dayThreeImage.image = weeklyWeather.dayThreeIcon
self.dayFourWeekDayLabel.text = "\(weeklyWeather.dayFourTime!)"
self.dayFourHighLow.text = "\(weeklyWeather.dayFourTemperatureMin)°/ \(weeklyWeather.dayFourTemperatureMax)°"
self.dayFourImage.image = weeklyWeather.dayFourIcon
self.dayFiveWeekDayLabel.text = "\(weeklyWeather.dayFiveTime!)"
self.dayFiveHighLow.text = "\(weeklyWeather.dayFiveTemperatureMin)°/ \(weeklyWeather.dayFiveTemperatureMax)°"
self.dayFiveImage.image = weeklyWeather.dayFiveIcon
self.daySixWeekDayLabel.text = "\(weeklyWeather.daySixTime!)"
self.daySixHighLow.text = "\(weeklyWeather.daySixTemperatureMin)°/ \(weeklyWeather.daySixTemperatureMax)°"
self.daySixImage.image = weeklyWeather.dayFiveIcon
//Weather Alerts
self.wAlerts.text = ""
self.wAlerts.text = "\(alertWeather.userAlert)"
})
} else {
let networkIssueController = UIAlertController(title: "Error", message: "Unable to load data. Connectivity error!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
networkIssueController.addAction(okButton)
let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
networkIssueController.addAction(cancelButton)
self.presentViewController(networkIssueController, animated: true, completion: nil)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
})
}
})
downloadTask.resume()
}
func refresh() {
initLocationManager()
self.temperatureLabel.alpha = 0
self.dayOneImage.alpha = 0
self.dayTwoImage.alpha = 0
self.dayThreeImage.alpha = 0
self.dayFourImage.alpha = 0
self.dayFiveImage.alpha = 0
self.daySixImage.alpha = 0
self.dayZeroTemperatureLow.alpha = 0
self.dayZeroTemperatureHigh.alpha = 0
self.windSpeedLabel.alpha = 0
self.humidityLabel.alpha = 0
self.precipitationLabel.alpha = 0
self.rainUILabel.alpha = 0
self.dayOneWeekDayLabel.alpha = 0
self.dayOneHighLow.alpha = 0
self.dayTwoWeekDayLabel.alpha = 0
self.dayTwoHighLow.alpha = 0
self.dayThreeWeekDayLabel.alpha = 0
self.dayThreeHighLow.alpha = 0
self.dayFourWeekDayLabel.alpha = 0
self.dayFourHighLow.alpha = 0
self.dayFiveWeekDayLabel.alpha = 0
self.dayFiveHighLow.alpha = 0
self.daySixWeekDayLabel.alpha = 0
self.daySixHighLow.alpha = 0
self.wAlerts.alpha = 0
self.weeklyForcastAnimation()
UIView.animateWithDuration(1.5, animations: {
self.temperatureLabel.alpha = 1.0
self.heatIndex.alpha = 1.0
self.dayOneImage.alpha = 1.0
self.dayTwoImage.alpha = 1.0
self.dayThreeImage.alpha = 1.0
self.dayFourImage.alpha = 1.0
self.dayFiveImage.alpha = 1.0
self.daySixImage.alpha = 1.0
self.dayZeroTemperatureLow.alpha = 1.0
self.dayZeroTemperatureHigh.alpha = 1.0
self.windSpeedLabel.alpha = 1.0
self.humidityLabel.alpha = 1.0
self.precipitationLabel.alpha = 1.0
self.rainUILabel.alpha = 1.0
self.dayOneWeekDayLabel.alpha = 1.0
self.dayOneHighLow.alpha = 1.0
self.dayTwoWeekDayLabel.alpha = 1.0
self.dayTwoHighLow.alpha = 1.0
self.dayThreeWeekDayLabel.alpha = 1.0
self.dayThreeHighLow.alpha = 1.0
self.dayFourWeekDayLabel.alpha = 1.0
self.dayFourHighLow.alpha = 1.0
self.dayFiveWeekDayLabel.alpha = 1.0
self.dayFiveHighLow.alpha = 1.0
self.daySixWeekDayLabel.alpha = 1.0
self.daySixHighLow.alpha = 1.0
self.wAlerts.alpha = 1.0
})
}
func weeklyForcastAnimation() {
//DAILY
self.dayZeroTemperatureLowLabel.transform = CGAffineTransformMakeTranslation(-300, 0)
self.dayZeroTemperatureHighLabel.transform = CGAffineTransformMakeTranslation(300, 0)
self.windBag.transform = CGAffineTransformMakeTranslation(0, -600)
self.umbrella.transform = CGAffineTransformMakeTranslation(0, -600)
self.rainDrop.transform = CGAffineTransformMakeTranslation(0, -600)
self.iconView.transform = CGAffineTransformMakeTranslation(-200, 0)
self.temperatureLabel.transform = CGAffineTransformMakeTranslation(300, 0)
self.summaryLabel.transform = CGAffineTransformMakeTranslation(0, -200)
self.heatIndex.transform = CGAffineTransformMakeTranslation(-350, 0)
//self.currentTimeLabel.transform = CGAffineTransformMakeTranslation(350,0)
self.userLocationLabel.transform = CGAffineTransformMakeTranslation(350, 0)
self.degreeButton.transform = CGAffineTransformMakeTranslation(350,0)
self.windUILabel.transform = CGAffineTransformMakeTranslation(-350,0)
self.humidityUILabel.transform = CGAffineTransformMakeTranslation(350,0)
self.degreeButton.transform = CGAffineTransformMakeTranslation(350, 0)
//WEEKLY
self.dayOneImage.transform = CGAffineTransformMakeTranslation(0, 100)
self.dayTwoImage.transform = CGAffineTransformMakeTranslation(0, 100)
self.dayThreeImage.transform = CGAffineTransformMakeTranslation(0, 100)
self.dayFourImage.transform = CGAffineTransformMakeTranslation(0, 100)
self.dayFiveImage.transform = CGAffineTransformMakeTranslation(0, 100)
self.daySixImage.transform = CGAffineTransformMakeTranslation(0, 100)
//DAILY SPRING ACTION
springWithDelay(0.9, 0.45, {
self.userLocationLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.60, {
self.degreeButton.transform = CGAffineTransformMakeTranslation(0, 0)
})
//springWithDelay(0.9, 0.45, {
// self.currentTimeLabel.transform = CGAffineTransformMakeTranslation(0, 0)
//})
springWithDelay(0.9, 0.25, {
self.windBag.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.35, {
self.umbrella.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.rainDrop.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.iconView.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.temperatureLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.60, {
self.summaryLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.heatIndex.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.dayZeroTemperatureLowLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.dayZeroTemperatureHighLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.userLocationLabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.windUILabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.humidityUILabel.transform = CGAffineTransformMakeTranslation(0, 0)
})
//WEEKLY FORCAST SPRING ACTION
springWithDelay(0.9, 0.25, {
self.dayOneImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.35, {
self.dayTwoImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.45, {
self.dayThreeImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.55, {
self.dayFourImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.65, {
self.dayFiveImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
springWithDelay(0.9, 0.75, {
self.daySixImage.transform = CGAffineTransformMakeTranslation(0, 0)
})
}
@IBAction func degreeButtonPressed(sender: AnyObject) {
}
//SOUNDS
func swooshsound() {
var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("swoosh", ofType: "wav")!)
println(alertSound)
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "infotab"{
let vc = segue.destinationViewController as! InfoTabViewController
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
agreatdaytocode
24,757 Pointsagreatdaytocode
24,757 PointsP.S Make sure you add "NSLocationAlwaysUsageDescription" to your info.plist :)