0

I'm trying to make a very simple cordova plugin to test/demonstrate repeating callbacks. The point is for me to learn how to do these relatively simple tasks, and gain confidence with them.

On Android I'm doing this, and it works fine:

in public boolean execute(...

if ("repeat".equals(action)) {
    int count = args.getInt(0);
    int delay = args.getInt(1);
    String message = args.getString(2);

    this.repeat(count, delay, message, callbackContext);
    return true;
}

And in the same class I have

private void repeat(final int count, final int delay, final String message, final CallbackContext callbackContext) {
    new Thread(new Runnable() {
        public void run() {
            for (int i = 0 ; i < count ; i++) {
                if (i > 0) { // only delay after the first iteration. Had this been at the end of the method, we'd have had to do some extra math to keep track of the last iteration.
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException e) {
                        //
                    }
                }
                try {
                    JSONObject json = new JSONObject();
                    json.put("message", message);
                    json.put("count", (i+1));
                    json.put("time", System.currentTimeMillis());

                    PluginResult result = new PluginResult(PluginResult.Status.OK, json);
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                } catch (JSONException e) {
                    PluginResult result = new PluginResult(PluginResult.Status.ERROR, "JSON Error: " + e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                }
            }

            callbackContext.success();
        }
    }).start();
}

Now, for a demonstration to work, I need to have the same function on at least iOS, but maybe also windows phone.

For iOS I have this so far, however it just spits off the repeated messages at once without delay, and I don't have an iPhone to test on.

- (void)repeat:(CDVInvokedUrlCommand*)command
{
    NSInteger count   = [[command.arguments objectAtIndex: 0] intValue];
    NSInteger delay   = [[command.arguments objectAtIndex: 1] intValue];
    NSString* message = [command.arguments objectAtIndex: 2];

    for (int i = 1; i <= count; i++)
    {
        NSDictionary *payload = [NSDictionary dictionaryWithObjectsAndKeys:
            message, @"message", 
            @(i), @"count", 
            @"0", @"time", 
            nil];

        CDVPluginResult* pluginResult = nil;
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:payload];
        [pluginResult setKeepCallbackAsBool:YES];

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

    CDVPluginResult* pluginResult = nil;
    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];

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

Here's the test plugin so far: EventTest plugin source.

A.Grandt
  • 2,242
  • 2
  • 20
  • 21

1 Answers1

0

It's unclear what you're asking for here, but if you're trying to replicate the behaviour of your Android example, then you're just missing the sleep behaviour. This question about delaying execution in Objective C should help.

[NSThread sleepForTimeInterval: delay];

At the top of your for-loop should be sufficient to stop the responses from being sent back in quick succession. This will block the main application thread, though, so it won't be the most elegant solution.

Community
  • 1
  • 1
Graham Harper
  • 487
  • 5
  • 11