ios - Delegate Call back method returns variable slow which causes variable nil while accessing from another class? -
in app delegate class, trying retrieve user current location class using delegate. retreived user curren location used in many parts of application.so ,i have set here in appdelegate
class
@uiapplicationmain class appdelegate: uiresponder, uiapplicationdelegate { var window: uiwindow? var helperlocation:helperlocationmanager? var currentlocation:cllocation? func application(application: uiapplication, didfinishlaunchingwithoptions launchoptions: [nsobject: anyobject]?) -> bool { //get current location , set other screens can use self.helperlocation = helperlocationmanager() self.helperlocation?.delegate = self return true } } extension appdelegate: sendlocationdelegate{ func sendcoordinates(loccoordinate:cllocation, placemark:clplacemark){ currentlocation = loccoordinate } }
and seems helperlocationmanager
class
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 location") case clauthorizationstatus.denied: println( "user denied access location please turn on location") // uiapplication.sharedapplication().openurl(nsurl(string: uiapplicationopensettingsurlstring)!) //may open here settings page , turn on 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 error" + error.localizeddescription) return } if placemarks.count > 0 { let pm = placemarks[0] as! clplacemark self.delegate?.sendcoordinates(locvalue,placemark: pm) } else { println("problem data received geocoder") } }) } func locationmanager(manager: cllocationmanager!, didfailwitherror error: nserror!) { println("your error ", error.localizeddescription) } }
i made call method trigger if there change in user location...
everything fine. helperlocationmanager
class sends current location method sendcoordinates
that implemented in appdelegate
, have set current location , accessing these location presentedviewcontroller
let appdelegate = uiapplication.sharedapplication().delegate as! appdelegate pickupdistancelocation = appdelegate.currentlocation
my problem when try access value fast enough in class during time interval delegate call method doesnot send me current location.i nil in case.but if wait 2-3 sec , go class value delegate.
can explain me doing wrong?
this architectural issue - say:
when try access value fast enough in class during time interval delegate call method not send me current location
you have invert - rather checking current location, risk of not having 1 because it's not been obtained yet, should let helperlocationmanager
notify when has location (the hollywood principle: don't call me, i'll call you).
this can done in different ways:
- using delegation pattern
- using event bus (which can implemented
nsnotificationcenter
) - using callbacks
there of course many other ways achieve same result.
the delegation pattern not best solution when there more 1 observer.
i use callback way, subscriber registering location updates providing closure helperlocationmanager
.
helperlocationmanager
can store callbacks array, , invoke each of them when location update available. optionally, can invoke closures right after registration, if location available.
last, subscriber must able unsubscribe, helperlocationmanager
should expose method removes callback internal list.
this idea - said, can done in several different ways, common rule invert how location passed.
note: make helperlocationmanager
singleton, , remove appdelegate
. if want use helperlocationmanager
, should contact directly, instead of having access through 3rd party (the app delegate).
Comments
Post a Comment