You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2012/02/17 02:38:49 UTC

[6/27] Rename PhoneGap to Cordova.

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVFileTransfer.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVFileTransfer.m b/CordovaLib/Classes/CDVFileTransfer.m
new file mode 100644
index 0000000..499bd47
--- /dev/null
+++ b/CordovaLib/Classes/CDVFileTransfer.m
@@ -0,0 +1,318 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVFileTransfer.h"
+#import "CDVFile.h"
+
+
+@implementation CDVFileTransfer
+
+- (void) upload:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
+    NSString* callbackId = [arguments objectAtIndex:0];
+    NSString* fileKey = (NSString*)[options objectForKey:@"fileKey"];
+    NSString* fileName = (NSString*)[options objectForKey:@"fileName"];
+    NSString* mimeType = (NSString*)[options objectForKey:@"mimeType"];
+    NSMutableDictionary* params = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary*)[options objectForKey:@"params"]];
+    NSString* filePath = (NSString*)[options objectForKey:@"filePath"];
+    NSString* server = (NSString*)[options objectForKey:@"server"];
+    CDVPluginResult* result = nil;
+    CDVFileTransferError errorCode = 0;
+
+    
+    NSURL* file;
+    NSData *fileData = nil;
+    
+    if ([filePath hasPrefix:@"/"]) {
+        file = [NSURL fileURLWithPath:filePath];
+    } else {
+        file = [NSURL URLWithString:filePath];
+    }
+    
+    NSURL *url = [NSURL URLWithString:server];
+    
+    
+    if (!url) {
+        errorCode = INVALID_URL_ERR;
+        NSLog(@"File Transfer Error: Invalid server URL");
+    } else if(![file isFileURL]) {
+        errorCode = FILE_NOT_FOUND_ERR;
+        NSLog(@"File Transfer Error: Invalid file path or URL");
+    } else {
+        // check that file is valid
+        NSFileManager* fileMgr = [[NSFileManager alloc] init];
+        BOOL bIsDirectory = NO;
+        BOOL bExists = [fileMgr fileExistsAtPath:[file path] isDirectory:&bIsDirectory];
+        if (!bExists || bIsDirectory) {
+            errorCode = FILE_NOT_FOUND_ERR;
+        } else {
+            // file exists, make sure we can get the data
+            fileData = [NSData dataWithContentsOfURL:file];
+            
+            if(!fileData) {
+                errorCode =  FILE_NOT_FOUND_ERR;
+                NSLog(@"File Transfer Error: Could not read file data");
+            }
+        }
+        [fileMgr release];
+    }
+    
+    if(errorCode > 0) {
+        //result = [PluginResult resultWithStatus: PGCommandStatus_OK messageAsInt: INVALID_URL_ERR cast: @"navigator.fileTransfer._castTransferError"];
+        
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: [self createFileTransferError:[NSString stringWithFormat:@"%d", errorCode] AndSource:filePath AndTarget:server]];
+        
+        [self writeJavascript:[result toErrorCallbackString:callbackId]];
+        return;
+    }
+    
+    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
+	[req setHTTPMethod:@"POST"];
+	
+//    Magic value to set a cookie
+	if([params objectForKey:@"__cookie"]) {
+		[req setValue:[params objectForKey:@"__cookie"] forHTTPHeaderField:@"Cookie"];
+		[params removeObjectForKey:@"__cookie"];
+		[req setHTTPShouldHandleCookies:NO];
+	}
+	
+	NSString *boundary = @"*****org.apache.cordova.formBoundary";
+    
+	NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
+	[req setValue:contentType forHTTPHeaderField:@"Content-Type"];
+    //Content-Type: multipart/form-data; boundary=*****org.apache.cordova.formBoundary
+	[req setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
+	NSString* userAgent = [[self.webView request] valueForHTTPHeaderField:@"User-agent"];
+	if(userAgent) {
+		[req setValue: userAgent forHTTPHeaderField:@"User-Agent"];
+	}
+
+    
+	NSMutableData *postBody = [NSMutableData data];
+	
+	NSEnumerator *enumerator = [params keyEnumerator];
+	id key;
+	id val;
+	
+	while ((key = [enumerator nextObject])) {
+		val = [params objectForKey:key];
+		if(!val || val == [NSNull null]) {
+			continue;	
+		}
+		// if it responds to stringValue selector (eg NSNumber) get the NSString
+		if ([val respondsToSelector:@selector(stringValue)]) {
+			val = [val stringValue];
+		}
+		// finally, check whether it is a NSString (for dataUsingEncoding selector below)
+		if (![val isKindOfClass:[NSString class]]) {
+			continue;
+		}
+		
+		[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+		[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
+		[postBody appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
+		[postBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+	}
+    
+	[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+	[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
+    [postBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
+    NSLog(@"fileData length: %d", [fileData length]);
+	[postBody appendData:fileData];
+	[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+    
+    //[req setValue:[[NSNumber numberWithInteger:[postBody length]] stringValue] forHTTPHeaderField:@"Content-Length"];
+	[req setHTTPBody:postBody];
+    
+	
+	CDVFileTransferDelegate* delegate = [[[CDVFileTransferDelegate alloc] init] autorelease];
+	delegate.command = self;
+    delegate.callbackId = callbackId;
+    delegate.source = server;
+    delegate.target = filePath;
+	
+	[NSURLConnection connectionWithRequest:req delegate:delegate];
+    
+}
+
+- (void) download:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
+    NSLog(@"File Transfer downloading file...");
+    
+    [self performSelectorInBackground:@selector(downloadFile:) withObject:arguments];
+}
+
+-(void) downloadFile:(NSMutableArray*)arguments {
+    NSString * callbackId = [arguments objectAtIndex:0];
+    NSString * sourceUrl = [arguments objectAtIndex:1];
+    NSString * filePath = [arguments objectAtIndex:2];
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString:sourceUrl] ];
+    NSArray * results = nil;
+    
+    NSLog(@"Write file %@", filePath);
+    NSError *error=[[[NSError alloc]init] autorelease];
+    
+    @try {
+        NSString * parentPath = [ filePath stringByDeletingLastPathComponent ];
+        
+        // check if the path exists => create directories if needed
+        if(![[NSFileManager defaultManager] fileExistsAtPath:parentPath ]) [[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:nil];
+        
+    	BOOL response = [data writeToFile:filePath options:NSDataWritingFileProtectionNone error:&error];
+        
+        if ( response == NO ) {
+        	// send our results back to the main thread
+            results = [NSArray arrayWithObjects: callbackId, [NSString stringWithFormat:@"%d", INVALID_URL_ERR], sourceUrl, filePath, nil];
+        	[self performSelectorOnMainThread:@selector(downloadFail:) withObject:results waitUntilDone:YES];
+    	} else {
+        	// jump back to main thread
+            results = [NSArray arrayWithObjects: callbackId, filePath, nil];
+        	[self performSelectorOnMainThread:@selector(downloadSuccess:) withObject:results waitUntilDone:YES];
+    	}
+    }
+    @catch (id exception) {
+        // jump back to main thread
+        results = [NSArray arrayWithObjects: callbackId, [NSString stringWithFormat:@"%d", FILE_NOT_FOUND_ERR], sourceUrl, filePath, nil];
+        [self performSelectorOnMainThread:@selector(downloadFail:) withObject:results waitUntilDone:YES];
+    }
+    
+    [pool drain];
+}
+
+-(void) downloadSuccess:(NSMutableArray *)arguments 
+{
+    NSString * callbackId = [arguments objectAtIndex:0];
+    NSString * filePath = [arguments objectAtIndex:1];
+
+    BOOL bDirRequest = NO;
+
+    NSLog(@"File Transfert Download success");
+    
+    CDVFile * file = [[[CDVFile alloc] init] autorelease];
+    
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: [file getDirectoryEntry: filePath isDirectory: bDirRequest] cast: @"window.localFileSystem._castEntry"];
+    [self writeJavascript: [result toSuccessCallbackString:callbackId]];
+}
+
+-(void) downloadFail:(NSMutableArray *)arguments 
+{
+    NSString * callbackId = [arguments objectAtIndex:0];
+    NSString * code = [arguments objectAtIndex:1];
+    NSString * source = [arguments objectAtIndex:2];
+    NSString * target = [arguments objectAtIndex:3];
+
+    NSLog(@"File Transfer Error: %@", source);
+    
+    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: [self createFileTransferError:code AndSource:source AndTarget:target]];
+                                    
+    [self writeJavascript: [pluginResult toErrorCallbackString:callbackId]];
+}
+
+-(NSMutableDictionary*) createFileTransferError:(NSString*)code AndSource:(NSString*)source AndTarget:(NSString*)target
+{
+    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:3];
+    [result setObject: code forKey:@"code"];
+	[result setObject: source forKey:@"source"];
+	[result setObject: target forKey:@"target"];
+    
+    return result;
+}
+
+@end
+
+
+@implementation CDVFileTransferDelegate
+
+@synthesize callbackId, source, target, responseData, command, bytesWritten;
+
+
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
+{
+    NSString* response = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+    // create dictionary to return FileUploadResult object
+    NSMutableDictionary* uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];
+    [uploadResult setObject: [response stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey: @"response"];
+    [uploadResult setObject:[NSNumber numberWithInt: self.bytesWritten] forKey:@"bytesSent"];
+    [uploadResult setObject:[NSNull null] forKey: @"responseCode"];
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: uploadResult cast: @"navigator.fileTransfer._castUploadResult"];
+    [command writeJavascript:[result toSuccessCallbackString: callbackId]];
+    [response release];
+}
+
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
+{
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: [command createFileTransferError: [NSString stringWithFormat: @"%d", CONNECTION_ERR] AndSource:source AndTarget:target]];
+    NSLog(@"File Transfer Error: %@", [error localizedDescription]);
+    [command writeJavascript:[result toErrorCallbackString: callbackId]];
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+{
+    [responseData appendData:data];
+}
+- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
+{
+    self.bytesWritten = totalBytesWritten;
+}
+/* TESTING ONLY CODE
+// use ONLY for testing with self signed certificates
+// uncomment and modify server name in connectiondidReceiveAuthenticationChallenge
+- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
+{
+    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
+}
+
+- (void)connection:(NSURLConnection *) connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
+{
+	if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
+	{
+        //NSLog(@"challenge host: %@", challenge.protectionSpace.host);
+		// we only trust our own domain
+		if ([challenge.protectionSpace.host isEqualToString:@"serverName.domain.com"]){
+            NSURLCredential* myCredential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
+            
+            [challenge.sender useCredential:myCredential forAuthenticationChallenge:challenge];
+			
+		}
+	}
+    
+	[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
+}
+// uncomment the above two methods for testing servers with self signed certificates
+// END TESTING ONLY CODE
+ */
+- (id) init
+{
+    if ((self = [super init])) {
+		self.responseData = [NSMutableData data];
+    }
+    return self;
+}
+
+- (void) dealloc
+{
+    [callbackId release];
+	[responseData release];
+	[command release];
+    [super dealloc];
+}
+
+
+@end;
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVInvokedUrlCommand.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVInvokedUrlCommand.h b/CordovaLib/Classes/CDVInvokedUrlCommand.h
new file mode 100644
index 0000000..b7beb7d
--- /dev/null
+++ b/CordovaLib/Classes/CDVInvokedUrlCommand.h
@@ -0,0 +1,39 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@interface CDVInvokedUrlCommand : NSObject {
+	NSString* className;
+	NSString* methodName;
+	NSMutableArray* arguments;
+	NSMutableDictionary* options;
+}
+
+@property(retain) NSMutableArray* arguments;
+@property(retain) NSMutableDictionary* options;
+@property(copy) NSString* className;
+@property(copy) NSString* methodName;
+
++ (CDVInvokedUrlCommand*) commandFromObject:(NSDictionary*)object;
+
+- (void) dealloc;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVInvokedUrlCommand.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVInvokedUrlCommand.m b/CordovaLib/Classes/CDVInvokedUrlCommand.m
new file mode 100644
index 0000000..45b0a1d
--- /dev/null
+++ b/CordovaLib/Classes/CDVInvokedUrlCommand.m
@@ -0,0 +1,51 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVInvokedUrlCommand.h"
+#import "JSONKit.h"
+
+@implementation CDVInvokedUrlCommand
+
+@synthesize arguments;
+@synthesize options;
+@synthesize className;
+@synthesize methodName;
+
++ (CDVInvokedUrlCommand*) commandFromObject:(NSDictionary*)object
+{
+    CDVInvokedUrlCommand* iuc = [[[CDVInvokedUrlCommand alloc] init] autorelease];
+    iuc.className = [object objectForKey:@"className"];
+    iuc.methodName = [object objectForKey:@"methodName"];
+    iuc.arguments = [object objectForKey:@"arguments"];
+    iuc.options = [object objectForKey:@"options"];
+
+    return iuc;
+}
+
+- (void) dealloc
+{
+    [arguments release];
+    [options release];
+    [className release];
+    [methodName release];
+    
+    [super dealloc];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVLocation.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVLocation.h b/CordovaLib/Classes/CDVLocation.h
new file mode 100755
index 0000000..e18aef6
--- /dev/null
+++ b/CordovaLib/Classes/CDVLocation.h
@@ -0,0 +1,91 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import <CoreLocation/CoreLocation.h>
+#import "CDVPlugin.h"
+
+enum CDVHeadingStatus {
+	HEADINGSTOPPED = 0,
+    HEADINGSTARTING,
+	HEADINGRUNNING,
+    HEADINGERROR
+};
+typedef NSUInteger CDVHeadingStatus;
+
+// simple object to keep track of heading information
+@interface CDVHeadingData : NSObject {
+    CDVHeadingStatus     headingStatus;
+    BOOL              headingRepeats;
+    CLHeading*        headingInfo;
+    NSMutableArray*   headingCallbacks;
+    NSString*         headingFilter;
+    
+}
+
+@property (nonatomic, assign) CDVHeadingStatus headingStatus;
+@property (nonatomic, assign) BOOL headingRepeats;
+@property (nonatomic, retain) CLHeading* headingInfo;
+@property (nonatomic, retain) NSMutableArray* headingCallbacks;
+@property (nonatomic, retain) NSString* headingFilter;
+
+@end
+
+@interface CDVLocation : CDVPlugin <CLLocationManagerDelegate> {
+
+    @private BOOL              __locationStarted;
+    CDVHeadingData*    headingData;
+}
+
+@property (nonatomic, retain) CLLocationManager *locationManager;
+@property (nonatomic, retain) CDVHeadingData* headingData;
+
+
+- (BOOL) hasHeadingSupport;
+
+- (void)startLocation:(NSMutableArray*)arguments
+     withDict:(NSMutableDictionary*)options;
+
+- (void)stopLocation:(NSMutableArray*)arguments
+    withDict:(NSMutableDictionary*)options;
+
+- (void)locationManager:(CLLocationManager *)manager
+    didUpdateToLocation:(CLLocation *)newLocation
+           fromLocation:(CLLocation *)oldLocation;
+
+- (void)locationManager:(CLLocationManager *)manager
+       didFailWithError:(NSError *)error;
+
+- (BOOL) isLocationServicesEnabled;
+
+- (void)getCurrentHeading:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+- (void)returnHeadingInfo: (NSString*) callbackId keepCallback: (BOOL) bRetain;
+
+- (void)stopHeading:(NSMutableArray*)arguments
+		   withDict:(NSMutableDictionary*)options;
+- (void) startHeadingWithFilter: (CLLocationDegrees) filter;
+- (void)locationManager:(CLLocationManager *)manager
+	   didUpdateHeading:(CLHeading *)heading;
+
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager;
+
+@end
+
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVLocation.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVLocation.m b/CordovaLib/Classes/CDVLocation.m
new file mode 100755
index 0000000..fb6cdb4
--- /dev/null
+++ b/CordovaLib/Classes/CDVLocation.m
@@ -0,0 +1,515 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import "CDVLocation.h"
+#import "CDVViewController.h"
+
+#pragma mark Constants
+
+#define kPGLocationErrorDomain          @"kPGLocationErrorDomain"
+#define kPGLocationDesiredAccuracyKey   @"desiredAccuracy"
+#define kPGLocationForcePromptKey       @"forcePrompt"
+#define kPGLocationDistanceFilterKey    @"distanceFilter"
+#define kPGLocationFrequencyKey         @"frequency"
+
+#pragma mark -
+#pragma mark Categories
+
+@interface NSError(JSONMethods)
+
+- (NSString*) JSONRepresentation;
+
+@end
+
+@interface CLLocation(JSONMethods)
+
+- (NSString*) JSONRepresentation;
+
+@end
+
+
+@interface CLHeading(JSONMethods)
+
+- (NSString*) JSONRepresentation;
+
+@end
+
+#pragma mark -
+#pragma mark CDVHeadingData
+
+@implementation CDVHeadingData
+
+@synthesize headingStatus, headingRepeats, headingInfo, headingCallbacks, headingFilter;
+-(CDVHeadingData*) init
+{
+    self = (CDVHeadingData*)[super init];
+    if (self) 
+	{
+        self.headingRepeats = NO;
+        self.headingStatus = HEADINGSTOPPED;
+        self.headingInfo = nil;
+        self.headingCallbacks = nil;
+        self.headingFilter = nil;
+    }
+    return self;
+}
+-(void) dealloc 
+{
+    self.headingInfo = nil;
+    self.headingCallbacks = nil;
+    self.headingFilter = nil;
+    [super dealloc];  
+}
+
+@end
+
+#pragma mark -
+#pragma mark CDVLocation
+
+@implementation CDVLocation
+
+@synthesize locationManager, headingData;
+
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView
+{
+    self = (CDVLocation*)[super initWithWebView:(UIWebView*)theWebView];
+    if (self) 
+	{
+        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
+        self.locationManager.delegate = self; // Tells the location manager to send updates to this object
+        __locationStarted = NO;
+        self.headingData = nil;        
+    }
+    return self;
+}
+
+- (BOOL) hasHeadingSupport
+{
+	BOOL headingInstancePropertyAvailable = [self.locationManager respondsToSelector:@selector(headingAvailable)]; // iOS 3.x
+	BOOL headingClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(headingAvailable)]; // iOS 4.x
+	
+	if (headingInstancePropertyAvailable) { // iOS 3.x
+		return [(id)self.locationManager headingAvailable];
+	} else if (headingClassPropertyAvailable) { // iOS 4.x
+		return [CLLocationManager headingAvailable];
+	} else { // iOS 2.x
+		return NO;
+	}
+}
+
+- (BOOL) isAuthorized
+{
+	BOOL authorizationStatusClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+    if (authorizationStatusClassPropertyAvailable)
+    {
+        NSUInteger authStatus = [CLLocationManager authorizationStatus];
+        return  (authStatus == kCLAuthorizationStatusAuthorized) || (authStatus == kCLAuthorizationStatusNotDetermined);
+    }
+    
+    // by default, assume YES (for iOS < 4.2)
+    return YES;
+}
+
+- (BOOL) isLocationServicesEnabled
+{
+	BOOL locationServicesEnabledInstancePropertyAvailable = [self.locationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 3.x
+	BOOL locationServicesEnabledClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 4.x
+    
+	if (locationServicesEnabledClassPropertyAvailable) 
+	{ // iOS 4.x
+		return [CLLocationManager locationServicesEnabled];
+	} 
+	else if (locationServicesEnabledInstancePropertyAvailable) 
+	{ // iOS 2.x, iOS 3.x
+		return [(id)self.locationManager locationServicesEnabled];
+	} 
+	else 
+	{
+		return NO;
+	}
+}
+
+- (void) startLocation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    if (![self isLocationServicesEnabled])
+	{
+		BOOL forcePrompt = NO;
+		// if forcePrompt is true iPhone will still show the "Location Services not active." Settings | Cancel prompt.
+		if ([options objectForKey:kPGLocationForcePromptKey]) 
+		{
+			forcePrompt = [[options objectForKey:kPGLocationForcePromptKey] boolValue];
+		}
+        
+		if (!forcePrompt)
+		{
+            NSError* error = [NSError errorWithDomain:kPGLocationErrorDomain code:1 userInfo:
+                              [NSDictionary dictionaryWithObject:@"Location services is not enabled" forKey:NSLocalizedDescriptionKey]];
+            NSLog(@"%@", [error JSONRepresentation]);
+            
+			NSString* jsCallback = [NSString stringWithFormat:@"navigator.geolocation.setError(%@);", [error JSONRepresentation]]; 
+			[super writeJavascript:jsCallback];
+            
+			return;
+		}
+    }
+    if (![self isAuthorized]) 
+    {
+        NSUInteger code = -1;
+        BOOL authStatusAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+        if (authStatusAvailable) {
+            code = [CLLocationManager authorizationStatus];
+        }
+        
+        NSError* error = [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:
+                          [NSDictionary dictionaryWithObject:@"App is not authorized for Location Services" forKey:NSLocalizedDescriptionKey]];
+        NSLog(@"%@", [error JSONRepresentation]);
+
+        NSString* jsCallback = [NSString stringWithFormat:@"navigator.geolocation.setError(%@);", [error JSONRepresentation]];
+        [super writeJavascript:jsCallback];
+        
+        return;
+    }
+	
+    // Tell the location manager to start notifying us of location updates. We
+    // first stop, and then start the updating to ensure we get at least one
+    // update, even if our location did not change.
+    [self.locationManager stopUpdatingLocation];
+    [self.locationManager startUpdatingLocation];
+    __locationStarted = YES;
+
+    if ([options objectForKey:kPGLocationDistanceFilterKey]) 
+	{
+        CLLocationDistance distanceFilter = [(NSString *)[options objectForKey:kPGLocationDistanceFilterKey] doubleValue];
+        self.locationManager.distanceFilter = distanceFilter;
+    }
+    
+    if ([options objectForKey:kPGLocationDesiredAccuracyKey]) 
+    {
+        int desiredAccuracy_num = [(NSString *)[options objectForKey:kPGLocationDesiredAccuracyKey] integerValue];
+        CLLocationAccuracy desiredAccuracy = kCLLocationAccuracyBest;
+        
+        if (desiredAccuracy_num < 10) {
+            desiredAccuracy = kCLLocationAccuracyBest;
+        }
+        else if (desiredAccuracy_num < 100) {
+            desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
+        }
+        else if (desiredAccuracy_num < 1000) {
+            desiredAccuracy = kCLLocationAccuracyHundredMeters;
+        }
+        else if (desiredAccuracy_num < 3000) {
+            desiredAccuracy = kCLLocationAccuracyKilometer;
+        }
+        else {
+            desiredAccuracy = kCLLocationAccuracyThreeKilometers;
+        }
+        
+        self.locationManager.desiredAccuracy = desiredAccuracy;
+    }
+}
+
+- (void) stopLocation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    if (__locationStarted)
+	{
+		if (![self isLocationServicesEnabled]) {
+			return;
+        }
+    
+		[self.locationManager stopUpdatingLocation];
+		__locationStarted = NO;
+	}
+}
+
+- (void) locationManager:(CLLocationManager *)manager
+							didUpdateToLocation:(CLLocation *)newLocation
+							fromLocation:(CLLocation *)oldLocation
+{
+	
+    NSString* jsCallback = [NSString stringWithFormat:@"navigator.geolocation.setLocation(%@);", [newLocation JSONRepresentation]];
+    [super writeJavascript:jsCallback];
+}
+// called to get the current heading
+// Will call location manager to startUpdatingHeading if necessary
+
+- (void)getCurrentHeading:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    NSString* callbackId = [arguments objectAtIndex:0];
+    NSNumber* repeats = [options valueForKey:@"repeats"];  // indicates this call will be repeated at regular intervals
+    
+    if ([self hasHeadingSupport] == NO) 
+    {
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageToErrorObject:20];
+        [super writeJavascript:[result toErrorCallbackString:callbackId]];
+    } else {
+       // heading retrieval does is not affected by disabling locationServices and authorization of app for location services
+        if (!self.headingData) {
+            self.headingData = [[[CDVHeadingData alloc] init] autorelease];
+        }
+        CDVHeadingData* hData = self.headingData;
+        
+        if (repeats != nil) {
+            hData.headingRepeats = YES;
+        }
+        if (!hData.headingCallbacks) {
+            hData.headingCallbacks = [NSMutableArray arrayWithCapacity:1];
+        }
+        // add the callbackId into the array so we can call back when get data
+        [hData.headingCallbacks addObject:callbackId]; 
+        
+        if (hData.headingStatus != HEADINGRUNNING && hData.headingStatus != HEADINGERROR) {
+            // Tell the location manager to start notifying us of heading updates
+            [self startHeadingWithFilter: 0.2];
+        }
+        else {
+            [self returnHeadingInfo: callbackId keepCallback:NO]; 
+        }
+    }
+  
+          
+} 
+// called to request heading updates when heading changes by a certain amount (filter)
+- (void)watchHeadingFilter:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    NSString* callbackId = [arguments objectAtIndex:0];
+    NSNumber* filter = [options valueForKey:@"filter"];
+    CDVHeadingData* hData = self.headingData;
+    if ([self hasHeadingSupport] == NO) {
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageToErrorObject:20];
+        [super writeJavascript:[result toErrorCallbackString:callbackId]];
+    } else {
+        if (!hData) {
+            self.headingData = [[[CDVHeadingData alloc] init] autorelease];
+            hData = self.headingData;
+        }
+        if (hData.headingStatus != HEADINGRUNNING) {
+            // Tell the location manager to start notifying us of heading updates
+            [self startHeadingWithFilter: [filter doubleValue]];
+        } else {
+            // if already running check to see if due to existing watch filter
+            if (hData.headingFilter && ![hData.headingFilter isEqualToString:callbackId]){
+                // new watch filter being specified
+                // send heading data one last time to clear old successCallback
+                [self returnHeadingInfo:hData.headingFilter keepCallback: NO];
+            } 
+            
+        }
+        // save the new filter callback and update the headingFilter setting
+        hData.headingFilter = callbackId;
+        // check if need to stop and restart in order to change value???
+        self.locationManager.headingFilter = [filter doubleValue];
+    } 
+}
+- (void)returnHeadingInfo: (NSString*) callbackId keepCallback: (BOOL) bRetain
+{
+    CDVPluginResult* result = nil;
+    NSString* jsString = nil;
+    CDVHeadingData* hData = self.headingData;
+    
+    if (hData && hData.headingStatus == HEADINGERROR) {
+        // return error
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageToErrorObject:0];
+        jsString = [result toErrorCallbackString:callbackId];
+    } else if (hData && hData.headingStatus == HEADINGRUNNING && hData.headingInfo) {
+        // if there is heading info, return it
+        CLHeading* hInfo = hData.headingInfo;
+        NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:4];
+        NSNumber* timestamp = [NSNumber numberWithDouble:([hInfo.timestamp timeIntervalSince1970]*1000)];
+        [returnInfo setObject:timestamp forKey:@"timestamp"];
+        [returnInfo setObject:[NSNumber numberWithDouble: hInfo.magneticHeading] forKey:@"magneticHeading"];
+        id trueHeading = __locationStarted ? (id)[NSNumber numberWithDouble:hInfo.trueHeading]:(id)[NSNull null];
+        [returnInfo setObject:trueHeading forKey:@"trueHeading"];
+        [returnInfo setObject:[NSNumber numberWithDouble: hInfo.headingAccuracy] forKey:@"headingAccuracy"];
+        
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: returnInfo];
+        [result setKeepCallbackAsBool:bRetain];
+
+        jsString = [result toSuccessCallbackString:callbackId];
+    }
+    if (jsString) {
+        [super writeJavascript:jsString];
+    }
+    
+    
+}
+
+- (void) stopHeading:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVHeadingData* hData = self.headingData;
+    if (hData && hData.headingStatus != HEADINGSTOPPED)
+	{
+		if (hData.headingFilter) {
+            // callback one last time to clear callback
+            [self returnHeadingInfo:hData.headingFilter keepCallback:NO];
+            hData.headingFilter = nil;
+        }
+        [self.locationManager stopUpdatingHeading];		
+        self.headingData = nil;
+	}
+}	
+
+
+// helper method to check the orientation and start updating headings
+- (void) startHeadingWithFilter: (CLLocationDegrees) filter
+{
+    if ([self.locationManager respondsToSelector: @selector(headingOrientation)]) {
+        UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
+        if (currentOrientation != UIDeviceOrientationUnknown) {
+            CDVViewController* pgViewController = (CDVViewController*)self.viewController;
+            
+            if ([pgViewController.supportedOrientations containsObject:
+                 [NSNumber numberWithInt:currentOrientation]]) {
+                
+                self.locationManager.headingOrientation = (CLDeviceOrientation)currentOrientation;
+                // FYI UIDeviceOrientation and CLDeviceOrientation enums are currently the same
+            }   
+        }
+    }
+    self.locationManager.headingFilter = filter;
+    [self.locationManager startUpdatingHeading];
+    self.headingData.headingStatus = HEADINGSTARTING;
+}
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
+{
+	return YES;
+}
+
+- (void) locationManager:(CLLocationManager *)manager
+						didUpdateHeading:(CLHeading *)heading
+{
+    CDVHeadingData* hData = self.headingData;
+    // save the data for next call into getHeadingData
+    hData.headingInfo = heading;
+    
+    if (hData.headingStatus == HEADINGSTARTING) {
+        hData.headingStatus = HEADINGRUNNING; // so returnHeading info will work
+        //this is the first update
+        for (NSString* callbackId in hData.headingCallbacks) {
+            [self returnHeadingInfo:callbackId keepCallback:NO];
+        }
+        [hData.headingCallbacks removeAllObjects];
+        if (!hData.headingRepeats && !hData.headingFilter) {
+            [self stopHeading:nil withDict:nil];
+        }
+    }
+    if (hData.headingFilter) {
+        [self returnHeadingInfo: hData.headingFilter keepCallback:YES];
+    }
+    hData.headingStatus = HEADINGRUNNING;  // to clear any error
+
+}
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
+{
+    NSLog(@"locationManager::didFailWithError %@", [error localizedFailureReason]);
+	NSString* jsCallback = @"";
+	
+    // Compass Error
+	if ([error code] == kCLErrorHeadingFailure)
+	{
+		CDVHeadingData* hData = self.headingData;
+        if (hData) {
+            if (hData.headingStatus == HEADINGSTARTING) {
+                // heading error during startup - report error
+                for (NSString* callbackId in hData.headingCallbacks) {
+                    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageToErrorObject:0];
+                    [super writeJavascript: [result toErrorCallbackString:callbackId]];
+                }
+                [hData.headingCallbacks removeAllObjects];
+            } // else for frequency watches next call to getCurrentHeading will report error
+            else if (hData.headingFilter) {
+                CDVPluginResult* resultFilter = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageToErrorObject:0];
+                [super writeJavascript: [resultFilter toErrorCallbackString:hData.headingFilter]];
+            }
+            hData.headingStatus = HEADINGERROR;
+        }
+	} 
+    // Location Error
+	else 
+	{
+		/*
+			W3C PositionError
+			 PositionError.UNKNOWN_ERROR = 0;  // equivalent to kCLErrorLocationUnknown=0
+			 PositionError.PERMISSION_DENIED = 1; // equivalent to kCLErrorDenied=1
+			 PositionError.POSITION_UNAVAILABLE = 2; // equivalent to kCLErrorNetwork=2
+		 
+			(any other errors are translated to PositionError.UNKNOWN_ERROR)
+		 */
+		if (error.code > kCLErrorNetwork) {
+            error = [NSError errorWithDomain:error.domain code:kCLErrorLocationUnknown userInfo:error.userInfo];
+		}
+		
+		jsCallback = [NSString stringWithFormat:@"navigator.geolocation.setError(%@);", [error JSONRepresentation]];
+	}
+	
+    [super writeJavascript:jsCallback];
+    
+	[self.locationManager stopUpdatingLocation];
+    __locationStarted = NO;
+}
+
+- (void) dealloc 
+{
+	self.locationManager.delegate = nil;
+	self.locationManager = nil;
+    self.headingData = nil;
+	[super dealloc];
+}
+
+@end
+
+#pragma mark -
+#pragma mark CLLocation(JSONMethods)
+
+@implementation CLLocation(JSONMethods)
+
+- (NSString*) JSONRepresentation
+{
+	return [NSString stringWithFormat:
+            @"{ timestamp: %.00f, \
+                coords: { latitude: %f, longitude: %f, altitude: %.02f, heading: %.02f, speed: %.02f, accuracy: %.02f, altitudeAccuracy: %.02f } \
+              }",
+            [self.timestamp timeIntervalSince1970] * 1000.0,
+            self.coordinate.latitude,
+            self.coordinate.longitude,
+            self.altitude,
+            self.course,
+            self.speed,
+            self.horizontalAccuracy,
+            self.verticalAccuracy
+			];
+}
+
+@end
+
+
+#pragma mark NSError(JSONMethods)
+
+@implementation NSError(JSONMethods)
+
+- (NSString*) JSONRepresentation
+{
+    return [NSString stringWithFormat:
+            @"{ code: %d, message: '%@'}", 
+			self.code, 
+			[self localizedDescription]
+            ];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVMotion.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVMotion.h b/CordovaLib/Classes/CDVMotion.h
new file mode 100644
index 0000000..4abb037
--- /dev/null
+++ b/CordovaLib/Classes/CDVMotion.h
@@ -0,0 +1,36 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import "CDVPlugin.h"
+
+
+@interface CDVMotion : CDVPlugin {
+}
+
+@property (readonly, getter=isDeviceMotionAvailable) BOOL deviceMotionAvailable;
+@property (readonly, getter=isDeviceOrientationAvailable) BOOL deviceOrientationAvailable;
+
+
+/* Checks whether the DeviceMotionEvent is available in the UIWebView */
+- (BOOL) deviceMotionAvailable; 
+/* Checks whether the DeviceOrientationEvent is available in the UIWebView */
+- (BOOL) deviceOrientationAvailable; 
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVMotion.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVMotion.m b/CordovaLib/Classes/CDVMotion.m
new file mode 100644
index 0000000..de94334
--- /dev/null
+++ b/CordovaLib/Classes/CDVMotion.m
@@ -0,0 +1,78 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import "CDVMotion.h"
+
+@implementation CDVMotion
+
+@synthesize deviceMotionAvailable, deviceOrientationAvailable;
+
+- (void) startDeviceMotionEvents
+{
+	// TODO: all iOS devices have accelerometers. Barring a way to detect if any listeners are bound,
+	// we will have to flood the UIWebView with these events
+	// If !isDeviceMotionAvailable, we pump out the events
+}
+
+- (void) startDeviceOrientationEvents
+{
+	// TODO: currently only iPhone 4 has support for gyro. We would only need to fill in support for iOS 4.0 and 4.1 
+	// (since the DeviceOrientationEvent is supported in in 4.2 for UIWebView)
+	// If gyro is available (see CMMotionManagerin CoreMotion.framework) AND !isDeviceOrientationAvailable, we pump out the events
+}
+
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView
+{
+    self = (CDVMotion*)[super initWithWebView:theWebView];
+    if (self) {
+		// this class has to be created somewhere for it to pump out events,
+		// perhaps in the AppDelegate
+		if (self.isDeviceMotionAvailable) {
+			[self startDeviceMotionEvents];
+		}
+		if (self.isDeviceOrientationAvailable) {
+			[self startDeviceOrientationEvents];
+		}
+    }
+    return self;
+}
+
+- (BOOL) deviceMotionAvailable
+{
+	NSString* js = @"window.DeviceMotionEvent != undefined";
+	NSString* result = [self.webView stringByEvaluatingJavaScriptFromString:js];
+	
+	return [result isEqualToString:@"true"];
+}
+
+- (BOOL) deviceOrientationAvailable
+{
+	NSString* js = @"window.DeviceOrientationEvent != undefined";
+	NSString* result = [self.webView stringByEvaluatingJavaScriptFromString:js];
+	
+	return [result isEqualToString:@"true"];
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVNotification.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVNotification.h b/CordovaLib/Classes/CDVNotification.h
new file mode 100644
index 0000000..daff4b2
--- /dev/null
+++ b/CordovaLib/Classes/CDVNotification.h
@@ -0,0 +1,41 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import <AudioToolbox/AudioServices.h>
+#import "CDVPlugin.h"
+
+@interface CDVNotification : CDVPlugin <UIAlertViewDelegate>{
+}
+
+- (void)alert:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; // confirm is just a variant of alert
+- (void)vibrate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+@end
+
+@interface CDVAlertView : UIAlertView {
+	NSString* callBackId;
+}
+@property(nonatomic, retain) NSString* callbackId;
+
+-(void) dealloc;
+
+@end
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVNotification.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVNotification.m b/CordovaLib/Classes/CDVNotification.m
new file mode 100644
index 0000000..6bb40b4
--- /dev/null
+++ b/CordovaLib/Classes/CDVNotification.m
@@ -0,0 +1,117 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import "CDVNotification.h"
+#import "NSDictionary+Extensions.h"
+
+
+@implementation CDVNotification
+
+
+- (void)alert:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+	NSString* callbackId = [arguments objectAtIndex:0];
+	NSString* message = [arguments objectAtIndex:1];
+	NSString* title   = [options objectForKey:@"title"];
+	NSString* button  = [options objectForKey:@"buttonLabel"];
+	
+	if (!title)
+        title = @"Alert";
+	if (!button)
+        button = @"OK";
+	
+	CDVAlertView *alertView = [[CDVAlertView alloc]
+							  initWithTitle:title
+							  message:message 
+							  delegate:self 
+							  cancelButtonTitle:nil 
+							  otherButtonTitles:nil];
+	
+	[alertView setCallbackId:callbackId];
+	NSArray* labels = [ button componentsSeparatedByString:@","];
+	
+	int count = [ labels count ];
+	
+	for(int n = 0; n < count; n++)
+	{
+		[ alertView addButtonWithTitle:[labels objectAtIndex:n]];
+	}
+	
+	[alertView show];
+	[alertView release];
+}
+
+
+- (void)prompt:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+	NSString* callbackId = [arguments objectAtIndex:0];
+	NSString* message = [arguments objectAtIndex:1];
+	NSString* title   = [options objectForKey:@"title"];
+	NSString* button  = [options objectForKey:@"buttonLabel"];
+    
+    if (!title)
+        title = @"Alert";
+    if (!button)
+        button = @"OK";
+    
+	CDVAlertView *openURLAlert = [[CDVAlertView alloc]
+								 initWithTitle:title
+								 message:message delegate:self cancelButtonTitle:button otherButtonTitles:nil];
+	[openURLAlert setCallbackId: callbackId];
+	[openURLAlert show];
+	[openURLAlert release];
+}
+
+/**
+ Callback invoked when an alert dialog's buttons are clicked.   
+ Passes the index + label back to JS
+ */
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    //NSString *buttonLabel = [alertView buttonTitleAtIndex:buttonIndex];
+	
+	CDVAlertView* pgAlertView = (CDVAlertView*) alertView;
+	CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsInt: ++buttonIndex]; 
+	[self writeJavascript:[result toSuccessCallbackString: [pgAlertView callbackId]]];
+	//NSString * jsCallBack = [NSString stringWithFormat:@"navigator.notification._alertCallback(%d,\"%@\");", ++buttonIndex, buttonLabel];    
+    //[webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+}
+ 
+- (void)vibrate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+	AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
+}
+
+@end
+
+@implementation CDVAlertView
+@synthesize callbackId;
+
+- (void) dealloc
+{
+	if (callbackId) {
+		[callbackId release];
+	}
+	
+	
+	[super dealloc];
+}
+@end
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVPlugin.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPlugin.h b/CordovaLib/Classes/CDVPlugin.h
new file mode 100644
index 0000000..662d4e9
--- /dev/null
+++ b/CordovaLib/Classes/CDVPlugin.h
@@ -0,0 +1,65 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "CDVPluginResult.h"
+#import "NSMutableArray+QueueAdditions.h"
+#import "CDVCommandDelegate.h"
+
+#define CDVPluginHandleOpenURLNotification	@"CDVPluginHandleOpenURLNotification"
+
+#define VERIFY_ARGUMENTS(args, expectedCount, callbackId) if (![self verifyArguments:args withExpectedCount:expectedCount andCallbackId:callbackId \
+callerFileName:__FILE__ callerFunctionName:__PRETTY_FUNCTION__]) { return; }
+
+
+@interface CDVPlugin : NSObject {
+}
+
+@property (nonatomic, retain) UIWebView* webView;
+@property (nonatomic, retain) NSDictionary* settings;
+@property (nonatomic, retain) UIViewController* viewController;
+@property (nonatomic, retain) id<CDVCommandDelegate> commandDelegate;
+
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings;
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView;
+
+- (void) handleOpenURL:(NSNotification*)notification;
+- (void) onAppTerminate;
+- (void) onMemoryWarning;
+
+/*
+ // see initWithWebView implementation
+ - (void) onPause {}
+ - (void) onResume {}
+ - (void) onOrientationWillChange {}
+ - (void) onOrientationDidChange {}
+ */
+
+- (id) appDelegate;
+- (UIViewController*) appViewController __attribute__((deprecated)); /* just use the .viewController property in the future */
+
+- (NSString*) writeJavascript:(NSString*)javascript;
+- (NSString*) success:(CDVPluginResult*)pluginResult callbackId:(NSString*)callbackId;
+- (NSString*) error:(CDVPluginResult*)pluginResult callbackId:(NSString*)callbackId;
+
+- (BOOL) verifyArguments:(NSMutableArray*)arguments withExpectedCount:(NSUInteger)expectedCount andCallbackId:(NSString*)callbackId 
+		  callerFileName:(const char*)callerFileName callerFunctionName:(const char*)callerFunctionName;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVPlugin.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPlugin.m b/CordovaLib/Classes/CDVPlugin.m
new file mode 100644
index 0000000..cdb4821
--- /dev/null
+++ b/CordovaLib/Classes/CDVPlugin.m
@@ -0,0 +1,161 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+
+#import "CDVPlugin.h"
+
+
+@implementation CDVPlugin
+@synthesize webView, settings, viewController, commandDelegate;
+
+
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings
+{
+    self = [self initWithWebView:theWebView];
+    if (self) {
+        self.settings = classSettings;
+	}
+    return self;
+}
+
+- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView
+{
+    self = [super init];
+    if (self) {
+		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppTerminate) name:UIApplicationWillTerminateNotification object:nil];
+		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
+		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:CDVPluginHandleOpenURLNotification object:nil];
+        
+		self.webView = theWebView;
+		
+		// You can listen to more app notifications, see:
+		// http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006728-CH3-DontLinkElementID_4
+		/*
+		 // NOTE: if you want to use these, make sure you uncomment the corresponding notification handler, and also the removeObserver in dealloc
+		 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil];
+		 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:UIApplicationWillEnterForegroundNotification object:nil];
+		 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationWillChange) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
+		 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationDidChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
+		 */
+	}
+    return self;
+}
+
+/* 
+	The arguments passed in should not included the callbackId. 
+	If argument count is not as expected, it will call the error callback using PluginResult (if callbackId is available),
+	or it will write to stderr using NSLog.
+ 
+	Usage is through the VERIFY_ARGUMENTS macro.
+ */
+- (BOOL) verifyArguments:(NSMutableArray*)arguments withExpectedCount:(NSUInteger)expectedCount andCallbackId:(NSString*)callbackId 
+		  callerFileName:(const char*)callerFileName callerFunctionName:(const char*)callerFunctionName 
+{
+	NSUInteger argc = [arguments count];
+	BOOL ok = (argc >= expectedCount); // allow for optional arguments
+	
+	if (!ok) {
+		NSString* errorString = [NSString stringWithFormat:@"Incorrect no. of arguments for plugin: was %d, expected %d", argc, expectedCount];
+		if (callbackId) {
+			NSString* callbackId = [arguments objectAtIndex:0];
+			CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorString];
+			[self writeJavascript:[pluginResult toErrorCallbackString:callbackId]];
+		} else {
+			NSString* fileName = [[[[NSString alloc] initWithBytes:callerFileName length:strlen(callerFileName) encoding:NSUTF8StringEncoding] autorelease] lastPathComponent];
+			NSLog(@"%@::%s - Error: %@", fileName, callerFunctionName, errorString);
+		}
+	}
+	
+	return ok;
+}
+
+/*
+// NOTE: for onPause and onResume, calls into JavaScript must not call or trigger any blocking UI, like alerts 
+- (void) onPause {}
+- (void) onResume {}
+- (void) onOrientationWillChange {}
+- (void) onOrientationDidChange {}
+*/
+
+/* NOTE: calls into JavaScript must not call or trigger any blocking UI, like alerts */
+- (void) handleOpenURL:(NSNotification*)notification
+{
+	// override to handle urls sent to your app
+	// register your url schemes in your App-Info.plist
+	
+	NSURL* url = [notification object];
+	if ([url isKindOfClass:[NSURL class]]) {
+		/* Do your thing! */
+	}
+}
+
+/* NOTE: calls into JavaScript must not call or trigger any blocking UI, like alerts */
+- (void) onAppTerminate
+{
+	// override this if you need to do any cleanup on app exit
+}
+
+- (void) onMemoryWarning
+{
+	// override to remove caches, etc
+}
+
+- (void) dealloc
+{
+	self.settings = nil;
+	self.webView = nil;
+	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];
+	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
+	[[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPluginHandleOpenURLNotification object:nil];
+	/*
+	 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
+	 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
+	 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
+	 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
+	 */
+    [super dealloc];
+}
+
+- (id) appDelegate
+{
+	return [[UIApplication sharedApplication] delegate];
+}
+
+/* deprecated - just use the viewController property */
+- (UIViewController*) appViewController
+{
+	return self.viewController;
+}
+
+- (NSString*) writeJavascript:(NSString*)javascript
+{
+	return [self.webView stringByEvaluatingJavaScriptFromString:javascript];
+}
+
+- (NSString*) success:(CDVPluginResult*)pluginResult callbackId:(NSString*)callbackId
+{
+	return [self writeJavascript:[NSString stringWithFormat:@"setTimeout(function() { %@; }, 0);", [pluginResult toSuccessCallbackString:callbackId]]];
+}
+
+- (NSString*) error:(CDVPluginResult*)pluginResult callbackId:(NSString*)callbackId
+{
+	return [self writeJavascript:[NSString stringWithFormat:@"setTimeout(function() { %@; }, 0);", [pluginResult toErrorCallbackString:callbackId]]];
+}
+
+@end
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVPluginResult.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPluginResult.h b/CordovaLib/Classes/CDVPluginResult.h
new file mode 100644
index 0000000..aeaf853
--- /dev/null
+++ b/CordovaLib/Classes/CDVPluginResult.h
@@ -0,0 +1,73 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+typedef enum {
+	CDVCommandStatus_NO_RESULT = 0,
+	CDVCommandStatus_OK,
+	CDVCommandStatus_CLASS_NOT_FOUND_EXCEPTION,
+	CDVCommandStatus_ILLEGAL_ACCESS_EXCEPTION,
+	CDVCommandStatus_INSTANTIATION_EXCEPTION,
+	CDVCommandStatus_MALFORMED_URL_EXCEPTION,
+	CDVCommandStatus_IO_EXCEPTION,
+	CDVCommandStatus_INVALID_ACTION,
+	CDVCommandStatus_JSON_EXCEPTION,
+	CDVCommandStatus_ERROR
+} CDVCommandStatus;
+	
+@interface CDVPluginResult : NSObject {
+	NSNumber* status;
+	id message;
+	NSNumber* keepCallback;
+	NSString* cast;
+	
+}
+
+@property (nonatomic, retain, readonly) NSNumber* status;
+@property (nonatomic, retain, readonly) id message;
+@property (nonatomic, retain)			NSNumber* keepCallback;
+@property (nonatomic, retain, readonly) NSString* cast;
+
+-(CDVPluginResult*) init;
++(void) releaseStatus;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsString: (NSString*) theMessage;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsArray: (NSArray*) theMessage;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsInt: (int) theMessage;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDouble: (double) theMessage;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDictionary: (NSDictionary*) theMessage;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsString: (NSString*) theMessage cast: (NSString*) theCast;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsArray: (NSArray*) theMessage cast: (NSString*) theCast;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsInt: (int) theMessage cast: (NSString*) theCast;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDouble: (double) theMessage cast: (NSString*) theCast;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDictionary: (NSDictionary*) theMessage cast: (NSString*) theCast;
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageToErrorObject: (int) errorCode;
+
+
+ 
+-(void) setKeepCallbackAsBool: (BOOL) bKeepCallback;
+
+
+-(NSString*) toJSONString;
+-(NSString*) toSuccessCallbackString: (NSString*) callbackId;
+-(NSString*) toErrorCallbackString: (NSString*) callbackId;
+
+-(void) dealloc;
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVPluginResult.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPluginResult.m b/CordovaLib/Classes/CDVPluginResult.m
new file mode 100644
index 0000000..57f1577
--- /dev/null
+++ b/CordovaLib/Classes/CDVPluginResult.m
@@ -0,0 +1,176 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ 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
+ 
+ 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
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVPluginResult.h"
+#import "JSONKit.h"
+#import "CDVDebug.h"
+
+@interface CDVPluginResult()
+
+-(CDVPluginResult*) initWithStatus:(CDVCommandStatus)statusOrdinal message: (id) theMessage cast: (NSString*) theCast;
+
+@end
+
+
+@implementation CDVPluginResult
+@synthesize status, message, keepCallback, cast;
+
+static NSArray* org_apache_cordova_CommandStatusMsgs;
+
++(void) initialize
+{
+	org_apache_cordova_CommandStatusMsgs = [[NSArray alloc] initWithObjects: @"No result",
+									  @"OK",
+									  @"Class not found",
+									  @"Illegal access",
+									  @"Instantiation error",
+									  @"Malformed url",
+									  @"IO error",
+									  @"Invalid action",
+									  @"JSON error",
+									  @"Error",
+									  nil];
+}
++(void) releaseStatus
+{
+	if (org_apache_cordova_CommandStatusMsgs != nil){
+		[org_apache_cordova_CommandStatusMsgs release];
+		org_apache_cordova_CommandStatusMsgs = nil;
+	}
+}
+		
+-(CDVPluginResult*) init
+{
+	return [self initWithStatus: CDVCommandStatus_NO_RESULT message: nil cast: nil];
+}
+-(CDVPluginResult*) initWithStatus:(CDVCommandStatus)statusOrdinal message: (id) theMessage cast: (NSString*) theCast{
+	self = [super init];
+	if(self) {
+		status = [NSNumber numberWithInt: statusOrdinal];
+		message = theMessage;
+		cast = theCast;
+		keepCallback = [NSNumber numberWithBool: NO];
+	}
+	return self;
+}		
+	
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: [org_apache_cordova_CommandStatusMsgs objectAtIndex: statusOrdinal] cast: nil] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsString: (NSString*) theMessage
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:nil] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsArray: (NSArray*) theMessage
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:nil] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsInt: (int) theMessage
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: [NSNumber numberWithInt: theMessage] cast:nil] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDouble: (double) theMessage
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: [NSNumber numberWithDouble: theMessage] cast:nil] autorelease];
+}
+
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDictionary: (NSDictionary*) theMessage
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:nil] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsString: (NSString*) theMessage cast: (NSString*) theCast
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:theCast] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsArray: (NSArray*) theMessage cast: (NSString*) theCast
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:theCast] autorelease];
+}
+
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsInt: (int) theMessage cast: (NSString*) theCast
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: [NSNumber numberWithInt: theMessage] cast:theCast] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDouble: (double) theMessage cast: (NSString*) theCast
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: [NSNumber numberWithDouble: theMessage] cast:theCast] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageAsDictionary: (NSDictionary*) theMessage cast: (NSString*) theCast
+{
+	return [[[self alloc] initWithStatus: statusOrdinal message: theMessage cast:theCast] autorelease];
+}
++(CDVPluginResult*) resultWithStatus: (CDVCommandStatus) statusOrdinal messageToErrorObject: (int) errorCode 
+{
+    NSDictionary* errDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:errorCode] forKey:@"code"];
+	return [[[self alloc] initWithStatus: statusOrdinal message: errDict cast:nil] autorelease];
+}
+
+
+-(void) setKeepCallbackAsBool:(BOOL)bKeepCallback
+{
+	[self setKeepCallback: [NSNumber numberWithBool:bKeepCallback]];
+}
+
+-(NSString*) toJSONString{
+    NSString* resultString = [[NSDictionary dictionaryWithObjectsAndKeys:
+                               self.status, @"status",
+                               self.message ? self.message : [NSNull null], @"message",
+                               self.keepCallback, @"keepCallback",
+                               nil] JSONString];
+	DLog(@"PluginResult:toJSONString - %@", resultString);
+	return resultString;
+}
+-(NSString*) toSuccessCallbackString: (NSString*) callbackId
+{
+	NSString* successCB;
+	
+	if ([self cast] != nil) {
+		successCB = [NSString stringWithFormat: @"var temp = %@(%@);\nCordova.callbackSuccess('%@',temp);", self.cast, [self toJSONString], callbackId];
+	}
+	else {
+		successCB = [NSString stringWithFormat:@"Cordova.callbackSuccess('%@',%@);", callbackId, [self toJSONString]];			
+	}
+	DLog(@"PluginResult toSuccessCallbackString: %@", successCB);
+	return successCB;
+}
+-(NSString*) toErrorCallbackString: (NSString*) callbackId
+{
+	NSString* errorCB = nil;
+	
+	if ([self cast] != nil) {
+		errorCB = [NSString stringWithFormat: @"var temp = %@(%@);\nCordova.callbackError('%@',temp);", self.cast, [self toJSONString], callbackId];
+	}
+	else {
+		errorCB = [NSString stringWithFormat:@"Cordova.callbackError('%@',%@);", callbackId, [self toJSONString]];
+	}
+	DLog(@"PluginResult toErrorCallbackString: %@", errorCB);
+	return errorCB;
+}	
+										 
+-(void) dealloc
+{
+	status = nil;
+	message = nil;
+	keepCallback = nil;
+	cast = nil;
+	
+	[super dealloc];
+}
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVReachability.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVReachability.h b/CordovaLib/Classes/CDVReachability.h
new file mode 100644
index 0000000..b00fb95
--- /dev/null
+++ b/CordovaLib/Classes/CDVReachability.h
@@ -0,0 +1,89 @@
+/*
+ 
+ File: Reachability.h
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+ 
+ Version: 2.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms.  If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple.  Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ 
+*/
+
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+#import <netinet/in.h>
+
+typedef enum {
+	NotReachable = 0,
+	ReachableViaWWAN, // this value has been swapped with ReachableViaWiFi for Cordova backwards compat. reasons
+	ReachableViaWiFi  // this value has been swapped with ReachableViaWWAN for Cordova backwards compat. reasons
+} NetworkStatus;
+#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
+
+@interface CDVReachability: NSObject
+{
+	BOOL localWiFiRef;
+	SCNetworkReachabilityRef reachabilityRef;
+}
+
+//reachabilityWithHostName- Use to check the reachability of a particular host name. 
++ (CDVReachability*) reachabilityWithHostName: (NSString*) hostName;
+
+//reachabilityWithAddress- Use to check the reachability of a particular IP address. 
++ (CDVReachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
+
+//reachabilityForInternetConnection- checks whether the default route is available.  
+//  Should be used by applications that do not connect to a particular host
++ (CDVReachability*) reachabilityForInternetConnection;
+
+//reachabilityForLocalWiFi- checks whether a local wifi connection is available.
++ (CDVReachability*) reachabilityForLocalWiFi;
+
+//Start listening for reachability notifications on the current run loop
+- (BOOL) startNotifier;
+- (void) stopNotifier;
+
+- (NetworkStatus) currentReachabilityStatus;
+//WWAN may be available, but not active until a connection has been established.
+//WiFi may require a connection for VPN on Demand.
+- (BOOL) connectionRequired;
+@end
+
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Classes/CDVReachability.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVReachability.m b/CordovaLib/Classes/CDVReachability.m
new file mode 100644
index 0000000..227264a
--- /dev/null
+++ b/CordovaLib/Classes/CDVReachability.m
@@ -0,0 +1,285 @@
+/*
+ 
+ File: Reachability.m
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+ 
+ Version: 2.2
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms.  If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple.  Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ 
+*/
+
+#import <sys/socket.h>
+#import <netinet/in.h>
+#import <netinet6/in6.h>
+#import <arpa/inet.h>
+#import <ifaddrs.h>
+#import <netdb.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+
+#import "CDVReachability.h"
+
+#define kShouldPrintReachabilityFlags 0
+
+static void CDVPrintReachabilityFlags(SCNetworkReachabilityFlags    flags, const char* comment)
+{
+#if kShouldPrintReachabilityFlags
+	
+    NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
+			(flags & kSCNetworkReachabilityFlagsIsWWAN)				  ? 'W' : '-',
+			(flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
+			
+			(flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
+			(flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
+			(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
+			(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+			(flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
+			(flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
+			(flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',
+			comment
+			);
+#endif
+}
+
+
+@implementation CDVReachability
+
+static void CDVReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
+{
+	#pragma unused (target, flags)
+//	NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
+//	NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
+    
+    // Converted the asserts above to conditionals, with safe return from the function
+    if (info == NULL) {
+        NSLog(@"info was NULL in ReachabilityCallback");
+        return;
+    }
+    
+    if (![(NSObject*) info isKindOfClass: [CDVReachability class]]) {
+        NSLog(@"info was wrong class in ReachabilityCallback");
+        return;
+    }
+
+	//We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
+	// in case someon uses the Reachablity object in a different thread.
+	NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
+	
+	CDVReachability* noteObject = (CDVReachability*) info;
+	// Post a notification to notify the client that the network reachability changed.
+	[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
+	
+	[myPool release];
+}
+
+- (BOOL) startNotifier
+{
+	BOOL retVal = NO;
+	SCNetworkReachabilityContext	context = {0, self, NULL, NULL, NULL};
+	if(SCNetworkReachabilitySetCallback(reachabilityRef, CDVReachabilityCallback, &context))
+	{
+		if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
+		{
+			retVal = YES;
+		}
+	}
+	return retVal;
+}
+
+- (void) stopNotifier
+{
+	if(reachabilityRef!= NULL)
+	{
+		SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+	}
+}
+
+- (void) dealloc
+{
+	[self stopNotifier];
+	if(reachabilityRef!= NULL)
+	{
+		CFRelease(reachabilityRef);
+	}
+	[super dealloc];
+}
+
++ (CDVReachability*) reachabilityWithHostName: (NSString*) hostName;
+{
+	CDVReachability* retVal = NULL;
+	SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
+	if(reachability!= NULL)
+	{
+		retVal= [[[self alloc] init] autorelease];
+		if(retVal!= NULL)
+		{
+			retVal->reachabilityRef = reachability;
+			retVal->localWiFiRef = NO;
+		}
+	}
+	return retVal;
+}
+
++ (CDVReachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
+{
+	SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
+	CDVReachability* retVal = NULL;
+	if(reachability!= NULL)
+	{
+		retVal= [[[self alloc] init] autorelease];
+		if(retVal!= NULL)
+		{
+			retVal->reachabilityRef = reachability;
+			retVal->localWiFiRef = NO;
+		}
+	}
+	return retVal;
+}
+
++ (CDVReachability*) reachabilityForInternetConnection;
+{
+	struct sockaddr_in zeroAddress;
+	bzero(&zeroAddress, sizeof(zeroAddress));
+	zeroAddress.sin_len = sizeof(zeroAddress);
+	zeroAddress.sin_family = AF_INET;
+	return [self reachabilityWithAddress: &zeroAddress];
+}
+
++ (CDVReachability*) reachabilityForLocalWiFi;
+{
+	struct sockaddr_in localWifiAddress;
+	bzero(&localWifiAddress, sizeof(localWifiAddress));
+	localWifiAddress.sin_len = sizeof(localWifiAddress);
+	localWifiAddress.sin_family = AF_INET;
+	// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
+	localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
+	CDVReachability* retVal = [self reachabilityWithAddress: &localWifiAddress];
+	if(retVal!= NULL)
+	{
+		retVal->localWiFiRef = YES;
+	}
+	return retVal;
+}
+
+#pragma mark Network Flag Handling
+
+- (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
+{
+	CDVPrintReachabilityFlags(flags, "localWiFiStatusForFlags");
+
+	BOOL retVal = NotReachable;
+	if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
+	{
+		retVal = ReachableViaWiFi;	
+	}
+	return retVal;
+}
+
+- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
+{
+	CDVPrintReachabilityFlags(flags, "networkStatusForFlags");
+	if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
+	{
+		// if target host is not reachable
+		return NotReachable;
+	}
+
+	BOOL retVal = NotReachable;
+	
+	if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
+	{
+		// if target host is reachable and no connection is required
+		//  then we'll assume (for now) that your on Wi-Fi
+		retVal = ReachableViaWiFi;
+	}
+	
+	
+	if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
+		(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
+	{
+			// ... and the connection is on-demand (or on-traffic) if the
+			//     calling application is using the CFSocketStream or higher APIs
+
+			if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
+			{
+				// ... and no [user] intervention is needed
+				retVal = ReachableViaWiFi;
+			}
+		}
+	
+	if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
+	{
+		// ... but WWAN connections are OK if the calling application
+		//     is using the CFNetwork (CFSocketStream?) APIs.
+		retVal = ReachableViaWWAN;
+	}
+	return retVal;
+}
+
+- (BOOL) connectionRequired;
+{
+	NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
+	SCNetworkReachabilityFlags flags;
+	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
+	{
+		return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
+	}
+	return NO;
+}
+
+- (NetworkStatus) currentReachabilityStatus
+{
+	NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
+	NetworkStatus retVal = NotReachable;
+	SCNetworkReachabilityFlags flags;
+	if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
+	{
+		if(localWiFiRef)
+		{
+			retVal = [self localWiFiStatusForFlags: flags];
+		}
+		else
+		{
+			retVal = [self networkStatusForFlags: flags];
+		}
+	}
+	return retVal;
+}
+@end