incubator-callback-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shaz...@apache.org
Subject docs commit: [CB-1072] iOS Plugin Authoring Guide
Date Thu, 19 Jul 2012 02:35:47 GMT
Updated Branches:
  refs/heads/master 085581ab5 -> 165a5d46b


[CB-1072] iOS Plugin Authoring Guide


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/165a5d46
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/tree/165a5d46
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/diff/165a5d46

Branch: refs/heads/master
Commit: 165a5d46b45605a815c4ea862c36878091aba238
Parents: 085581a
Author: Shazron Abdullah <shazron@gmail.com>
Authored: Wed Jul 18 19:35:39 2012 -0700
Committer: Shazron Abdullah <shazron@gmail.com>
Committed: Wed Jul 18 19:35:39 2012 -0700

----------------------------------------------------------------------
 docs/en/edge/guide/plugin-development/ios/index.md |  148 ++++++++++++++-
 1 files changed, 142 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-docs/blob/165a5d46/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 6915691..a39d4f8 100644
--- a/docs/en/edge/guide/plugin-development/ios/index.md
+++ b/docs/en/edge/guide/plugin-development/ios/index.md
@@ -1,21 +1,157 @@
 ---
 license: Licensed to the Apache Software Foundation (ASF) under one
-         or more contributor license agreements.  See the NOTICE file
+         or more contributor license agreements. See the NOTICE file
          distributed with this work for additional information
-         regarding copyright ownership.  The ASF licenses this file
+         regarding copyright ownership. The ASF licenses this file
          to you under the Apache License, Version 2.0 (the
          "License"); you may not use this file except in compliance
-         with the License.  You may obtain a copy of the License at
+         with the License. You may obtain a copy of the License at
 
            http://www.apache.org/licenses/LICENSE-2.0
 
          Unless required by applicable law or agreed to in writing,
          software distributed under the License is distributed on an
          "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-         KIND, either express or implied.  See the License for the
+         KIND, either express or implied. See the License for the
          specific language governing permissions and limitations
          under the License.
 ---
 
-Developing a Plugin on iOS
-==========================
+# Developing a Plugin on iOS
+
+Writing a plugin requires an understanding of the architecture of Cordova-iOS. Cordova-iOS
consists of a UIWebView where intercept commands passed in as url changes. These plugins are
represented as class mappings in the Cordova.plist file, under the Plugins key.
+
+A plugin is an Objective-C class that extends the `CDVPlugin` class.
+
+## Plugin Class Mapping 
+
+The JavaScript portion of a plugin always uses the `cordova.exec` method as follows:
+
+    exec(<successFunction>, <failFunction>, <service>, <action>,
[<args>]);
+
+This will marshall a request from the UIWebView to the iOS native side, more or less boiling
down to calling the `action` method on the `service` class, with the arguments passed in the
`args` Array. 
+
+The `options` parameter for the Objective-C plugin method is being deprecated, and it should
not be used. For legacy reasons - the last JavaScript object passed in the `args` Array will
be passed in as the `options` dictionary of the method in Objective-C. You must make sure
that any JavaScript object that is passed in as an element in the `args` array occurs as the
last item in the Array, if not it will throw off the array index of all subsequent parameters
of the Array in Objective-C. Only one JavaScript object is supported for the options dictionary,
and only the last one encountered will be passed to the native method. It is because of these
error-prone reasons that they are being deprecated.
+
+The plugin must be added to `Plugins` key (a Dictionary) of the `Cordova.plist` file in your
Cordova-iOS application's project folder.
+
+    <key>service_name</key>
+    <string>PluginClassName</string>
+
+The key `service_name` should match what you use in the JavaScript `exec` call, and the value
will be the name of the Objective-C class of the plugin. Without this added, the plugin may
compile but will not be reachable by Cordova.
+
+## Writing an iOS Cordova Plugin
+
+We have JavaScript fire off a plugin request to the native side. We have the iOS Objective-C
plugin mapped properly via the `Cordova.plist` file. So what does the final iOS Objective-C
Plugin class look like?
+
+What gets dispatched to the plugin via JavaScript's `exec` function gets passed into the
corresponding Plugin class's `action` method. Most method implementations look like this:
+
+    - (void) myMethod:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+    {
+        NSString* callbackId = [arguments objectAtIndex:0];
+
+        CDVPluginResult* pluginResult = nil;
+        NSString* javaScript = nil;
+
+        @try {
+            NSString* myarg = [arguments objectAtIndex:1];
+
+            if (myarg != nil) {
+                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+                javaScript = [pluginResult toSuccessCallbackString:callbackId];
+            } 
+        } @catch (id exception) {
+            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION
messageAsString:[exception reason]];
+            javaScript = [pluginResult toErrorCallbackString:callbackId];
+        }
+
+        [self writeJavascript:javaScript];
+    }
+    
+
+### Echo Plugin iOS Plugin
+
+We would add the following to the `Plugins` key (a Dictionary) of the project's `Cordova.plist`
file:
+
+    <key>Echo</key>
+    <string>Echo</string>
+
+Then we would add the following files (`Echo.h` and `Echo.m`) to the Plugins folder inside
our Cordova-iOS
+application folder:
+
+    /********* Echo.h Cordova Plugin Header *******/
+
+    #import <Cordova/CDVPlugin.h>
+
+    @interface Echo : CDVPlugin
+
+    - (void) echo:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+    @end
+    
+    /********* Echo.m Cordova Plugin Implementation *******/
+    
+    #import "Echo.h"
+    #import <Cordova/CDVPluginResult.h>
+
+    @implementation Echo
+
+    - (void) echo:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+    {
+        NSString* callbackId = [arguments objectAtIndex:0];
+
+        CDVPluginResult* pluginResult = nil;
+        NSString* javaScript = nil;
+
+        @try {
+            NSString* echo = [arguments objectAtIndex:1];
+
+            if (echo != nil && [echo length] > 0) {
+                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
+                javaScript = [pluginResult toSuccessCallbackString:callbackId];
+            } else {
+                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+                javaScript = [pluginResult toErrorCallbackString:callbackId];
+            }
+        } @catch (NSException* exception) {
+            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION
messageAsString:[exception reason]];
+            javaScript = [pluginResult toErrorCallbackString:callbackId];
+        }
+
+        [self writeJavascript:javaScript];
+    }
+
+    @end
+
+
+Let's take a look at the code. At the top we have all of the necessary Cordova imports. Our
class extends from `CDVPlugin` - very important. 
+
+This plugin only supports one action, the `echo` action. First, we grab the `callbackId`
parameter, which is always the 0th item in the arguments array. Next, we grab the echo string
using the `objectAtIndex` method on our `args`, telling it we want to get the 1st 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.
+
+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
+
+See other methods that you can override in:
+
+1. [CDVPlugin.h](https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPlugin.h)
+2. [CDVPlugin.m](https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPlugin.m)
+
+For example, you can hook into the pause, resume, app terminate and handleOpenURL events.
+
+## 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/)
+
+## Common Pitfalls
+
+* 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);
+        
\ No newline at end of file


Mime
View raw message