ios - Send command and wait for reply - Wait for delegate in Obj-C -


my goal achieve synchronized communication custom device i.e. next command can send when reply received. i'm doing in way

device class implements devicedelegate protocol

//device.h @class device;  @protocol devicedelegate <nsobject> - (void)didrecivereplywithdata:(nsdata *)data; @end  @interface device : nsobject {} 

in deviceviewcontroller implementation:

@interface deviceviewcontroller() {     bool waitingforreply = false; } @end  @implementation deviceviewcontroller  - (void)sendcommandwithdata:(nsdata *)data {     if ( waitingforreply == false)     {         //send command code         waitingforreply = true;     } }  - (void)didrecivereplywithdata:(nsdata *)data {     //code     waitingforreply = false; }  @end 

but wish in more elegant way i.e. using gcd (semaphores?) blocks (completionhandler?). ideas?

ps. sorry, forgot mention: commands sended device while

waitingforreply = true 

should ignored!!!.

possibly best approach here create queue of commands nsoperationqueue.

since, presumably, communication device asynchronous have subclass nsoperation encapsulate communication.

@interface devicecommandoperation : nsoperation <devicedelegate> @property (nonatomic, assign) bool waitingforreply; @property (nonatomic, copy) nsdata *datatosend; @property (nonatomic, copy) nsdata *datareceived; @end  @implementation devicecommandoperation  - (instancetype)initwithdata:(nsdata *)datatosend {     self = [super init];     if (self)     {         _datatosend = [datatosend copy];     }     return self; }  - (void)setwaitingforreply:(bool)waitingforreply {     if (_waitingforreply != waitingforreply)     {         [self willchangevalueforkey:@"isexecuting"];         [self willchangevalueforkey:@"isfinished"];          _waitingforreply = waitingforreply;          [self didchangevalueforkey:@"isexecuting"];         [self didchangevalueforkey:@"isfinished"];      } }  - (void)start {     self.waitingforreply = yes;      // simulate sending command , waiting response.     // need replace actual communication mechanism.     dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(0.5 * nsec_per_sec)), dispatch_get_main_queue(), ^{         // in reality call presumably come device         [self didreceivereplywithdata:somedata];     }); }  - (void)didreceivereplywithdata:(nsdata *)data {     self.datareceived = data;     self.waitingforreply = no; }  #pragma mark - nsoperation  - (bool)isasynchronous {     return yes; }  - (bool)isexecuting {     return _waitingforreply; }  - (bool)isfinished {     return !_waitingforreply; }  @end 

this operation could used deviceviewcontroller (it better architecturally have responsibility elsewhere that's not topic of question).

@interface deviceviewcontroller () @property (nonatomic, strong) nsoperationqueue *operationqueue; @end  @implementation deviceviewcontroller  - (nsoperationqueue *)operationqueue {     if (_operationqueue == nil)     {         _operationqueue = [[nsoperationqueue alloc] init];     }     return _operationqueue; }  - (void)sendnextcommand {     nsdata *data = // data next command     [self sendcommandwithdata:data]; }  - (void)sendcommandwithdata:(nsdata *)data {     nslog(@"queueing operation");      devicecommandoperation *operation = [[devicecommandoperation alloc] initwithdata:data];      // operation's completionblock gets called on background queue     [operation setcompletionblock:^{         nslog(@"devicecommandoperation completed");          // process operation.datareceived          [self sendnextcommand];     }];      [self.operationqueue addoperation:operation]; }  @end 

this approach allow determine (if any) command send next, based on reply previous command.

if know of "commands" want send , don't need finer grained control create instances of devicecommandoperation each command, set queue's maxconcurrentoperationcount 1, , add each devicecommandoperation queue (in order want them processed).


Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -