在我的app委托类中,我正在尝试使用委托从另一个类中检索用户当前位置。这个已转换的用户Curren位置将用于我的应用程序的许多部分。所以,我已在AppDelegate
类
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var helperLocation:HelperLocationManager?
var currentLocation:CLLocation?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//get the current location and set it so all other screens can use it
self.helperLocation = HelperLocationManager()
self.helperLocation?.delegate = self
return true
}
}
extension AppDelegate: SendLocationDelegate{
func sendCoOrdinates(loccoordinate:CLLocation, placemark:CLPlacemark){
currentLocation = loccoordinate
}
}
这似乎是我的HelperLocationManager
班级
protocol SendLocationDelegate{
func sendCoOrdinates(coordinates:CLLocation,placemark:CLPlacemark)
}
class HelperLocationManager: NSObject {
var locationManager = CLLocationManager()
var delegate:SendLocationDelegate?
override init() {
super.init()
var code = CLLocationManager.authorizationStatus()
if code == CLAuthorizationStatus.NotDetermined {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
locationManager.delegate = self
}
}
extension HelperLocationManager: CLLocationManagerDelegate{
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case CLAuthorizationStatus.Restricted:
println( "Restricted Access to location")
case CLAuthorizationStatus.Denied:
println( "User denied access to location please turn on the location")
// UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
//may be open here settings page and say to turn on the setting location services
default:
locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue = locations.last as! CLLocation
locationManager.stopUpdatingLocation()
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks,error)-> Void in
if (error != nil) {
println("Reverse geocoder failed with error" + error.localizedDescription)
return
}
if placemarks.count > 0 {
let pm = placemarks[0] as! CLPlacemark
self.delegate?.sendCoOrdinates(locValue,placemark: pm)
} else {
println("Problem with the data received from geocoder")
}
})
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Your error is ", error.localizedDescription)
}
}
如果用户位置发生任何变化,我会调用我的回调方法...
一切都很好。 HelperLocationManager
类将当前位置发送到sendCoOrdinates
中实现的方法AppDelegate
我已设置当前位置,现在我从presentedViewController
访问这些位置
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
pickUpDistanceLocation = appDelegate.currentLocation
我的问题是当我尝试在时间间隔内在另一个类中非常快地访问该值时,委托回调方法不会将我发送给我当前的位置。在这种情况下我得到零。但是如果我等待2-3秒并转到另一个班级,我从代表处获得价值。
任何人都可以解释一下我做错了什么吗?
答案 0 :(得分:1)
这是一个架构问题 - 你说:
当我尝试在时间间隔内在另一个类中非常快地访问该值时,委托回调方法不会向我发送当前位置
你必须反过来 - 而不是检查当前位置,而不是因为尚未获得当前位置,你应该让HelperLocationManager
在有位置时通知(好莱坞原则:不要打电话给我,我会打电话给你)。
这可以通过不同的方式完成:
NSNotificationCenter
实现)当然还有很多其他方法可以达到相同的效果。
当有多个观察者时,委托模式可能不是最佳解决方案。
我会使用回调方式,订阅者通过向HelperLocationManager
提供闭包来注册位置更新。
HelperLocationManager
可以将所有回调存储到数组中,并在位置更新可用时调用每个回调。可选地,如果位置已经可用,它可以在注册后立即调用闭包。
最后,订阅者必须能够取消订阅,因此HelperLocationManager
应该公开一个从内部列表中删除回调的方法。
这只是一个想法 - 如上所述,它可以通过几种不同的方式完成,通常的规则是反转位置的传递方式。
注意:我会将HelperLocationManager
设为单身,然后将其从AppDelegate
中移除。如果我想使用HelperLocationManager
,我应该直接与其联系,而不是通过第三方(应用代表)访问。