位置坐标在swift中返回nil

时间:2015-04-19 01:45:34

标签: ios iphone xcode swift ios8

坐标返回nil,我已经在plist文件中输入了requestAlwaysAuthorization和requestWhenInUseAuthorization,但是没有任何反应。 这是我的代码。

这段代码怎么了?我无法找到错误的位置。它只是为cordinates返回nil

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 userLocationLabel: 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.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)")
        }
}


func getCurrentWeatherData() -> Void {
    userLocation = "\(userLatitude),\(userLongitude)"

    // DC cord. = "44.029002,-92.855343"
    //URL
    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)
     println(error)
            //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.
}


}

2 个答案:

答案 0 :(得分:1)

也许您已经在未显示的代码中处理了所有这些情况,但这里列出了我认为代码中缺少的内容:

  • 我不认为您在代码中致电initLocationManager
  • getCurrentWeatherData()在您的viewDidLoad()工作中,您需要从locationManager(didUpdateLocations)拨打电话。
  • 仅在应用程序选项中添加requestAlwaysAuthorizationrequestWhenInUseAuthorization是不够的。您还需要向NSLocationAlwaysUsageDescription提供解释您需要访问权限的文本。
  • 您需要检查授权状态。如果未确定,则需要请求访问并实施回调以等待用户响应。如果您使用未确定的任何其他状态调用requestAuthorization,我相信该功能不会执行任何操作,也不会提供任何反馈。
  • 为了进一步排除故障,我建议你(1)获取授权状态,(2)将一个打印语句或断点放到locationManager(didUpdateLocations)以查看它是否被调用。

答案 1 :(得分:1)

我也在努力完成这一步。 MirekE指出了所有重点。我已经建立了MirekE所说的内容,并展示了一些代码,可能有助于更详细地解释它。
步骤1)确保您的info.plist具有以下内容。不要忘记给它们一个值 - 需要使用您的位置来获取当前位置的天气。或者沿着这些方向的一些事情。
NSLocationAlwaysUsageDescription
隐私 - 位置使用说明
NSLocationWhenInUseUsageDescription

步骤2)我将此代码添加到我的项目中并与步骤1结合,然后我将获得允许位置服务的警报视图。

        //this is part of my viewDidLoad()
        if ( ios8() ) {
        locationManager.requestAlwaysAuthorization()
        locationManager.requestWhenInUseAuthorization()
    }
    locationManager.startUpdatingLocation()

/*
iOS 8 Utility
*/
func ios8() -> Bool {
    if ( NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {
        return false
    } else {
        return true
    }
}

步骤3)我使用默认值将它们存储起来用于其他目的。

    // MARK: CLLocationManagerDelegate
public func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    var location:CLLocation = locations[locations.count-1]as! CLLocation

    if (location.horizontalAccuracy > 0) {
        self.locationManager.stopUpdatingLocation()
        self.defaults.setDouble(location.coordinate.latitude, forKey: "lat")
        self.defaults.setDouble(location.coordinate.longitude, forKey: "lon")
        println("lat \(location.coordinate.latitude)  lon \(location.coordinate.longitude)")
        defaults.synchronize()
        updateLocationInfo() // This is where you would call your getCurrentWeatherData()      

    }
}
// MARK: locationManager
public func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println(error)
    self.loading.text = "Can't get your location!"
}