ios - Reactive Cocoa: trouble with switchToLatest in chain of operations -
i'm having trouble disposing of 1 of operations in chained list of operations. i'm trying use reactive cocoa provide stream of locations while user logged in , has granted access location services.
i'm still pretty new world of reactive cocoa , functional reactive programming in general, here's i've got far:
@weakify(self); // signal of bool racsignal *loggedinsignal = [[self loggedinsignal] distinctuntilchanged]; // signal of clauthorizationstatus racsignal *currentstatesignal = [[self currentauthorizationsignal] distinctuntilchanged]; // defer creation of location stream signal until subscribed racsignal *locationsignal = [racsignal defer:^racsignal * { @strongify(self); // uninterrupted stream of locations, retry stream if error occurs return [[self locationssignal] retry]; }]; racsignal *locationservicesdisabledsignal = [racsignal createsignal:^racdisposable *(id<racsubscriber> subscriber) { @strongify(self); [self locationservicesdisabled]; [subscriber sendcompleted]; return nil; }]; self.disposable = [[[[[[loggedinsignal map:^id(nsnumber *loggedin) { return [loggedin boolvalue] ? currentstatesignal : [racsignal empty]; }] switchtolatest] map:^id(nsnumber *currentstatus) { if (clauthorizationstatuscanbeginmonitoring([currentstatus intvalue])) { return locationsignal; } return locationservicesdisabledsignal; }] switchtolatest] subscribenext:^(cllocation *location) { @strongify(self); cllocationcoordinate2d coord = location.coordinate; [self.output receivednewlocationwithlatitude:coord.latitude longitude:coord.longitude accuracy:location.horizontalaccuracy timestamp:location.timestamp]; }] asscopeddisposable]; this works expected when authorisation status changes, starting/stopping location stream. when logging out, location stream continues provide locations. it's if authstatesignal not disposed of, adjusting authorisation status still start/stop stream, though loggedinsignal had returned no last value.
i tried this:
(previous code above)... return locationservicesdisabledsignal; }] switchtolatest] takeuntil:[loggedinsignal skip:1]] subscribenext:^(cllocation *location) { (etc)... after second switchtolatest stop signal after next log in/out, besides feeling kind of "hack-ish", stopped location stream events after 1 log in/out, never start them again. proper method of handling scenario?
also, feels i'm using locationservicesdisabledsignal in wrong way. want method called when authstatesignal returns status indicating location services disabled, can react accordingly, putting method call inside [racsignal createsignal:] block way doesn't feel reactive cocoa-ey. other tips on how of i'm trying reactive cocoa way appreciated too.
the reason isn't working out when return [racsignal empty]; values nor propogate through chain because [racsignal empty]; not send next events. try this:
// signal of bool racsignal *loggedinsignal = [[self loggedinsignal] distinctuntilchanged]; // signal of clauthorizationstatus racsignal *currentstatesignal = [[self currentauthorizationsignal] distinctuntilchanged]; // defer creation of location stream signal until subscribed racsignal *locationsignal = [racsignal defer:^racsignal * { @strongify(self); // uninterrupted stream of locations, retry stream if error occurs return [[self locationssignal] retry]; }]; racsignal *locationservicesdisabledsignal = [racsignal createsignal:^racdisposable *(id<racsubscriber> subscriber) { @strongify(self); [self locationservicesdisabled]; [subscriber sendcompleted]; return nil; }]; self.disposable = [[[racsignal combinelatest:@[loggedinsignal, currentstatesignal]] flattenmap: ^racstream * (ractuple *tuple){ nsnumber* loggedin = [tuple first]; nsnumber* currentstatus = [tuple second]; if([loggedin boolvalue] && clauthorizationstatuscanbeginmonitoring([currentstatus intvalue])){ return locationsignal } else { return locationservicesdisabledsignal } } ] subscribenext:^(cllocation *location) { @strongify(self); cllocationcoordinate2d coord = location.coordinate; [self.output receivednewlocationwithlatitude:coord.latitude longitude:coord.longitude accuracy:location.horizontalaccuracy timestamp:location.timestamp]; }]
Comments
Post a Comment