Ios 单例类变量在初始化函数外返回nil
我正在使用XCode 8学习Swift,并一直在开发这个简单的天气应用程序。该应用程序从openweather.org公共API中获取当前天气和未来10天天气预报的数据 从带有静态纬度和经度的JSON格式的openweather API中提取数据,并将其显示在UI中(包括用于当前天气的UIView和用于10天预测数据的UITableView),一切正常。该应用程序看起来像 这个- 现在,我正在实现Ios 单例类变量在初始化函数外返回nil,ios,swift,xcode,swift3,Ios,Swift,Xcode,Swift3,我正在使用XCode 8学习Swift,并一直在开发这个简单的天气应用程序。该应用程序从openweather.org公共API中获取当前天气和未来10天天气预报的数据 从带有静态纬度和经度的JSON格式的openweather API中提取数据,并将其显示在UI中(包括用于当前天气的UIView和用于10天预测数据的UITableView),一切正常。该应用程序看起来像 这个- 现在,我正在实现CoreLocation协议,以使用GPS设备获取纬度和经度(而不是硬编码坐标),然后将纬度/经度
CoreLocation
协议,以使用GPS设备获取纬度和经度(而不是硬编码坐标),然后将纬度/经度存储到单例类变量中。singleton类如下所示-
import CoreLocation
class Location{
static var sharedInstance = Location()
private init(){}
var latitude: Double!
var longitude: Double!
}
现在在我的主ViewController中,有一个函数可以初始化LocationManager
,以获取设备位置(lat/long),然后将其存储到单例类变量latitude
和longitude
。该函数是从视图中调用的。主视图控制器如下所示-
import UIKit
import CoreLocation
class WeatherVC: UIViewController, UITableViewDelegate, UITableViewDataSource, CLLocationManagerDelegate {
....
....
//IBOutlets etc.
//Some vars etc.
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startMonitoringSignificantLocationChanges()
......//a few more lines of code here
print(Location.sharedInstance.latitude,Location.sharedInstance.longitude)// this prints nil, nil
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
locationAuthStatus()
}
func locationAuthStatus(){
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse{
currentLocation = locationManager.location
Location.sharedInstance.latitude = currentLocation.coordinate.latitude
Location.sharedInstance.longitude = currentLocation.coordinate.longitude
print(Location.sharedInstance.latitude,Location.sharedInstance.longitude) //this prints the correct values
}else{
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
}
}
}
现在我有了一个常量文件,其中保存了应用程序的某些全局常量,如openweather API URL等。在这里,我想使用单例类变量Location.sharedInstance.latitude
和Location.sharedInstance.longitude
。常量文件有一个变量,它构造了2个API URL,如下所示-
let CURRENT_WEATHER_URL = "\(BASE_URL)\(LATITUDE)\(Location.sharedInstance.latitude)\(LONGITUDE)\(Location.sharedInstance.longitude)\(APP_ID)\(API_KEY)"
let FORECAST_WEATHER_URL = "\(FORECAST_URL)\(LATITUDE)\(Location.sharedInstance.latitude)\(LONGITUDE)\(Location.sharedInstance.longitude)\(FORECAST_CNT)\(APP_ID)\(API_KEY)"
但是,Location.sharedInstance.latitude
和Location.sharedInstance.latitude
总是在locationAuthStatus()之外返回nil
函数,因此CURRENT\u WEATHER\u URL
和FORECAST\u WEATHER\u URL
中的lat/long值显示为nil
,导致API调用失败。locationAuthStatus()
函数中有一个print语句,用于正确打印Location.sharedInstance.latitude
和Location.sharedInstance.longitude
值,但不知怎的,这些值拒绝传播到应用程序的其余部分(在其他类中)。我尝试从项目中的所有其他类中打印这些,所有这些类都返回nil
一般来说,我仍在学习更多关于单例类和Swift的知识,但如果能深入了解我的错误,我将不胜感激。viewDidLoad
在ViewDidAspect
之前执行,因此如果您从ViewDidAspect
调用locationAuthStatus()
(在此处设置lat/long),它们还没有在viewDidLoad
中设置。哇!我的印象是执行顺序是相反的。谢谢,让我试试。你不能像这样简单地访问locationManager.location。它是异步的。您需要添加方法func locationManager(manager:CLLocationManager,didUpdateLocations locations:[CLLocation]){
并获取locations
属性,您还需要调用locationManager.startUpdatingLocation()
或requestLocation()
用于单个位置。别忘了也实现位置管理器(\uuquo:didFailWithError:)
@LeoDabus谢谢。现在,只需按照@Samantha的建议从viewdiload
调用locationAuthStatus()
就可以了(我刚刚试过),但现在我对你提到的功能很好奇,因为我怀疑我目前的代码在手机上可能不太好用(目前只使用模拟器)。