6

I need to implement some functionality that triggers an action on an interval and emits the results back to javascript.

To simplify things I will use the echo example from the PhoneGap documentation:

- (void)echo:(CDVInvokedUrlCommand*)command
{
  [self.commandDelegate runInBackground:^{

    CDVPluginResult* pluginResult = nil;
    NSString* echo = [command.arguments objectAtIndex:0];

    if (echo != nil && [echo length] > 0) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
    } else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

  }];
}

I want to make this call the same callback with the echo every second until stop is called.

I've created a timer that calls another function every second, but I don't know how to keep the context of the callback to send the result to.

//Starts Timer
- (void)start:(CDVInvokedUrlCommand*)command
{
  [NSTimer scheduledTimerWithTimeInterval:1.0
                                  target:self
                                  selector:@selector(action:)
                                  userInfo:nil
                                  repeats:YES];
}

//Called Action
-(void)action:(CDVInvokedUrlCommand*)command
{
  [self.commandDelegate runInBackground:^{

    NSLog(@"TRIGGERED");

  }];
}

Any help keeping this within the context of the callback would be great. Thanks!

Serge P
  • 1,173
  • 3
  • 25
  • 39
boom
  • 10,856
  • 9
  • 43
  • 64

3 Answers3

10

You'll want to have something like:

NSString *myCallbackId;

as an instance-level variable (outside of any method, so it retains its value). Set it when you first come in to the plugin code:

myCallbackId = command.callbackId;

Then, right after you instantiate a PluginResult, but before using it, do something like:

[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];

That will tell it to keep the callback valid for future use.

Then do something like:

[self.commandDelegate sendPluginResult:pluginResult callbackId:myCallbackId];
Konrad Dzwinel
  • 36,825
  • 12
  • 98
  • 105
Tony Hursh
  • 141
  • 1
  • 4
  • This is good, (although I am not an Objective C dev, but you have documented your code so I somewhat understanding it). My question is after doing this how you will be able to handle it in the Javascript. In my implementation (in Android of course), I get a console log about `secondCallback` since I've 'setKeepCallback' to true, and when the second result is passed then I get that console log. So, how to handle this. [[1](http://stackoverflow.com/questions/19177991)][ [2](http://stackoverflow.com/questions/19558535)] – Anas Azeem Oct 28 '13 at 10:51
  • I don't know -- I haven't tried it with Android. If it works, and the only issue is a console log message, I'd just ignore it. :-) – Tony Hursh Oct 28 '13 at 13:25
  • Not at all @Tony, the log isn't an issue. Its a green light that I am getting something when `setKeepCallback` id set to `true`. My concern is, I want to handle those 'second callback' in my code. Moreover, you don't have to worry about Android, just the javascript (or HTML) to handle them. – Anas Azeem Oct 28 '13 at 13:29
2

hi for getting many callback to js you can use setKeepCallback(true)

eg

 PluginResult p3=   new PluginResult(PluginResult.Status.OK, "0");
 p3.setKeepCallback(true);
Arjun T Raj
  • 3,187
  • 1
  • 21
  • 44
  • Thanks, can you provide some more context around how this works? I don't quite understand how I can implement this. – boom Sep 12 '13 at 12:36
  • Arjun T Raj: Please answer my questions. [Question 1](http://stackoverflow.com/questions/19177991/), [Question 2](http://stackoverflow.com/questions/19558535/) – Anas Azeem Oct 28 '13 at 10:54
0

Just if it helps somebody, in Android I am not using PluginResult and I am still able to keep a reference to the CallbackContext and call it anytime. I am not sure if this is the right way, but I can confirm that it worked for me.