Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 139F1DEBB for ; Sun, 21 Oct 2012 02:52:51 +0000 (UTC) Received: (qmail 80212 invoked by uid 500); 21 Oct 2012 02:52:50 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 80118 invoked by uid 500); 21 Oct 2012 02:52:49 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 80091 invoked by uid 99); 21 Oct 2012 02:52:48 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 21 Oct 2012 02:52:48 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 4942245798; Sun, 21 Oct 2012 02:52:48 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: agrieve@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [2/2] docs commit: Update iOS plugin guide for changes in 2.2.0. Message-Id: <20121021025248.4942245798@tyr.zones.apache.org> Date: Sun, 21 Oct 2012 02:52:48 +0000 (UTC) Update iOS plugin guide for changes in 2.2.0. - [commandDelegate sendPluginResult] instead of [webView writeJavaScript] - Add a section on threading. - Remove mention of alert() causing dead-lock (we now think that's fixed) Also, remove @try for exceptions. No core plugins have that, so it's shouldn't be in the docs. Bug: https://issues.apache.org/jira/browse/CB-1608 Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/commit/26bdfa75 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/tree/26bdfa75 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/diff/26bdfa75 Branch: refs/heads/master Commit: 26bdfa75c0e429df107f8f543ecdebe45e1566c2 Parents: 5f6768f Author: Andrew Grieve Authored: Sat Oct 20 22:43:52 2012 -0400 Committer: Andrew Grieve Committed: Sat Oct 20 22:43:52 2012 -0400 ---------------------------------------------------------------------- docs/en/edge/guide/plugin-development/ios/index.md | 82 +++++++-------- 1 files changed, 39 insertions(+), 43 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/blob/26bdfa75/docs/en/edge/guide/plugin-development/ios/index.md ---------------------------------------------------------------------- diff --git a/docs/en/edge/guide/plugin-development/ios/index.md b/docs/en/edge/guide/plugin-development/ios/index.md index 5d1b447..ab30d3a 100644 --- a/docs/en/edge/guide/plugin-development/ios/index.md +++ b/docs/en/edge/guide/plugin-development/ios/index.md @@ -46,39 +46,33 @@ We have JavaScript fire off a plugin request to the native side. We have the iOS What gets dispatched to the plugin via JavaScript's `exec` function gets passed into the corresponding Plugin class's `action` method. A plugin method has this signature: - - (void) myMethod:(CDVInvokedUrlCommand*)command + - (void)myMethod:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; - NSString* javaScript = nil; - - @try { - NSString* myarg = [command.arguments objectAtIndex:0]; - - if (myarg != nil) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - javaScript = [pluginResult toSuccessCallbackString:command.callbackId]; - } - } @catch (id exception) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; - javaScript = [pluginResult toErrorCallbackString:command.callbackId]; - } + NSString* myarg = [command.arguments objectAtIndex:0]; - [self writeJavascript:javaScript]; + if (myarg != nil) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was null"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } 1. [CDVInvokedUrlCommand.h](https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVInvokedUrlCommand.h) 2. [CDVPluginResult.h](https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPluginResult.h) +3. [CDVCommandDelegate.h](https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVCommandDelegate.h) ## Plugin Signatures The **new signature** supported beginning in **Cordova 2.1.0** is: - - (void) myMethod:(CDVInvokedUrlCommand*)command; + - (void)myMethod:(CDVInvokedUrlCommand*)command; The **old (deprecated)** signature is: - - (void) myMethod:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + - (void)myMethod:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; Basically, the options dictionary has been removed for the new signature, and the callbackId is not the 0th index item for the arguments array, but it is now in a separate property. @@ -98,7 +92,7 @@ application folder: @interface Echo : CDVPlugin - - (void) echo:(CDVInvokedUrlCommand*)command; + - (void)echo:(CDVInvokedUrlCommand*)command; @end @@ -109,27 +103,18 @@ application folder: @implementation Echo - - (void) echo:(CDVInvokedUrlCommand*)command + - (void)echo:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; - NSString* javaScript = nil; - - @try { - NSString* echo = [command.arguments objectAtIndex:0]; - - if (echo != nil && [echo length] > 0) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; - javaScript = [pluginResult toSuccessCallbackString:command.callbackId]; - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; - javaScript = [pluginResult toErrorCallbackString:command.callbackId]; - } - } @catch (NSException* exception) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; - javaScript = [pluginResult toErrorCallbackString:command.callbackId]; + 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 writeJavascript:javaScript]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end @@ -139,9 +124,25 @@ Let's take a look at the code. At the top we have all of the necessary Cordova i This plugin only supports one action, the `echo` action. First, we grab the echo string using the `objectAtIndex` method on our `args`, telling it we want to get the 0th parameter in the arguments array. We do a bit of parameter checking: make sure it is not `nil`, and make sure it is not a zero-length string. -If it is, we return a `PluginResult` with an `ERROR` status. If all of those checks pass, then we return a `PluginResult` with an `OK` status, and pass in the `echo` string we received in the first place as a parameter. Then, we convert the `PluginResult` to JavaScript by calling either the `toSuccessCallbackString` (if it was OK) or `toErrorCallbackString` (if it was an error) methods. +If it is, we return a `PluginResult` with an `ERROR` status. If all of those checks pass, then we return a `PluginResult` with an `OK` status, and pass in the `echo` string we received in the first place as a parameter. + +Finally, we send the result to `self.commandDelegate`, which will execute the JavaScript that will callback to success or failure callbacks of the exec method on the JavaScript side. If the success callback was called, it will pass the `echo` parameter as a parameter. + +## Threading + +Although UIWebViews run on a dedicated thread, plugin methods are executed on the UI thread. If your plugin requires a non-trivial amount of processing or requires a blocking call, you should make use of a background thread. An example: + + - (void)myPluginMethod:(CDVInvokedUrlCommand*)command + { + [self.commandDelegate runInBackground:^{ + NSString* payload = nil; + // Some blocking logic... + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload]; + // sendPluginResult is thread-safe. + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } -Finally we write the JavaScript back to the UIWebView, which will execute the JavaScript that will callback to success or failure callbacks of the exec method on the JavaScript side. If the success callback was called, it will pass the `echo` parameter as a parameter. ## Advanced Plugin Functionality @@ -154,7 +155,7 @@ For example, you can hook into the pause, resume, app terminate and handleOpenUR ## Debugging Plugins -To debug the Objective-C side, you would use Xcode's built in debugger. For JavaScript, you can use [Weinre, an Apache Cordova Project](https://github.com/apache/incubator-cordova-weinre) or [iWebInspector, a third-party utility](http://www.iwebinspector.com/) +To debug the Objective-C side, you would use Xcode's built in debugger. For JavaScript, on iOS 5.0 you can use [Weinre, an Apache Cordova Project](https://github.com/apache/incubator-cordova-weinre) or [iWebInspector, a third-party utility](http://www.iwebinspector.com/) For iOS 6, you would use Safari 6.0 to simply attach to your app running in the iOS 6 Simulator. @@ -162,11 +163,6 @@ For iOS 6, you would use Safari 6.0 to simply attach to your app running in the * Don't forget to add your plugin's mapping to Cordova.plist - if you forgot, an error will be printed to the Xcode console log * Don't forget to add any hosts you connect to in the [whitelist](guide_whitelist_index.md.html#Domain%20Whitelist%20Guide) - if you forgot, an error will be printed to the Xcode console log -* If you handle the resume event, and the app resumes, you can hang the app if you send out a JavaScript call that executes a native function, like alerts. To be safe, wrap your JavaScript call in a setTimeout call, with a timeout value of zero: - - setTimeout(function() { - // do your thing here! - }, 0); ## Deprecated Plugin Signature Note