You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/02/21 20:43:55 UTC

[2/4] 2.5.0rc1 (2.5.0 in package.json). Removed old test related to webworks scripts. Updated lbiraries to 2.5.0rc1. Added a VERSION file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
index 8e05658..4ccdce6 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
@@ -19,7 +19,10 @@
 
 #import "CDV.h"
 
-#include <CFNetwork/CFNetwork.h>
+#import <AssetsLibrary/ALAsset.h>
+#import <AssetsLibrary/ALAssetRepresentation.h>
+#import <AssetsLibrary/ALAssetsLibrary.h>
+#import <CFNetwork/CFNetwork.h>
 
 @interface CDVFileTransfer ()
 // Sets the requests headers for the request.
@@ -27,7 +30,7 @@
 // Creates a delegate to handle an upload.
 - (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command;
 // Creates an NSData* for the file for the given upload arguments.
-- (NSData*)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command;
+- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command;
 @end
 
 // Buffer size to use for streaming uploads.
@@ -254,35 +257,60 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     return delegate;
 }
 
-- (NSData*)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command
+- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command
 {
     NSString* target = (NSString*)[command.arguments objectAtIndex:0];
     NSError* __autoreleasing err = nil;
-    // Extract the path part out of a file: URL.
-    NSString* filePath = [target hasPrefix:@"/"] ? [target copy] : [[NSURL URLWithString:target] path];
 
-    // Memory map the file so that it can be read efficiently even if it is large.
-    NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
+    // return unsupported result for assets-library URLs
+    if ([target hasPrefix:kCDVAssetsLibraryPrefix]) {
+        // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
+        ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+            if (asset) {
+                // We have the asset!  Get the data and send it off.
+                ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
+                Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
+                NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
+                NSData* fileData = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
+                [self uploadData:fileData command:command];
+            } else {
+                // We couldn't find the asset.  Send the appropriate error.
+                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+                [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+            }
+        };
+        ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+            // Retrieving the asset failed for some reason.  Send the appropriate error.
+            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
+            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        };
+
+        ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
+        [assetsLibrary assetForURL:[NSURL URLWithString:target] resultBlock:resultBlock failureBlock:failureBlock];
+        return;
+    } else {
+        // Extract the path part out of a file: URL.
+        NSString* filePath = [target hasPrefix:@"/"] ? [target copy] : [[NSURL URLWithString:target] path];
+
+        // Memory map the file so that it can be read efficiently even if it is large.
+        NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
 
-    if (err != nil) {
-        NSLog(@"Error opening file %@: %@", target, err);
+        if (err != nil) {
+            NSLog (@"Error opening file %@: %@", target, err);
+        }
+        [self uploadData:fileData command:command];
     }
-    return fileData;
 }
 
 - (void)upload:(CDVInvokedUrlCommand*)command
 {
-    NSString* argPath = [command.arguments objectAtIndex:0];
-
-    // return unsupported result for assets-library URLs
-    if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
-        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"upload not supported for assets-library URLs."];
-        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-        return;
-    }
-
     // fileData and req are split into helper functions to ease the unit testing of delegateForUpload.
-    NSData* fileData = [self fileDataForUploadCommand:command];
+    // First, get the file data.  This method will call `uploadData:command`.
+    [self fileDataForUploadCommand:command];
+}
+
+- (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command
+{
     NSURLRequest* req = [self requestForUploadCommand:command fileData:fileData];
 
     if (req == nil) {
@@ -396,13 +424,15 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
                                       AndSource:(NSString*)source
                                       AndTarget:(NSString*)target
                                   AndHttpStatus:(int)httpStatus
+                                        AndBody:(NSString*)body
 {
-    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:4];
+    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:5];
 
     [result setObject:[NSNumber numberWithInt:code] forKey:@"code"];
     [result setObject:source forKey:@"source"];
     [result setObject:target forKey:@"target"];
     [result setObject:[NSNumber numberWithInt:httpStatus] forKey:@"http_status"];
+    [result setObject:body forKey:@"body"];
     NSLog(@"FileTransferError %@", result);
 
     return result;
@@ -426,7 +456,8 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
 - (void)connectionDidFinishLoading:(NSURLConnection*)connection
 {
     NSString* uploadResponse = nil;
-    BOOL downloadResponse;
+    NSString* downloadResponse = nil;
+    BOOL downloadWriteOK = NO;
     NSMutableDictionary* uploadResult;
     CDVPluginResult* result = nil;
     NSError* __autoreleasing error = nil;
@@ -437,9 +468,10 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     NSLog(@"File Transfer Finished with response code %d", self.responseCode);
 
     if (self.direction == CDV_TRANSFER_UPLOAD) {
+        uploadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+
         if ((self.responseCode >= 200) && (self.responseCode < 300)) {
             // create dictionary to return FileUploadResult object
-            uploadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
             uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];
             if (uploadResponse != nil) {
                 [uploadResult setObject:uploadResponse forKey:@"response"];
@@ -448,7 +480,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
             [uploadResult setObject:[NSNumber numberWithInt:self.responseCode] forKey:@"responseCode"];
             result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:uploadResult];
         } else {
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode]];
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:uploadResponse]];
         }
     }
     if (self.direction == CDV_TRANSFER_DOWNLOAD) {
@@ -464,11 +496,12 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
                     [[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:nil];
                 }
 
-                downloadResponse = [self.responseData writeToFile:self.target options:NSDataWritingFileProtectionNone error:&error];
+                downloadWriteOK = [self.responseData writeToFile:self.target options:NSDataWritingFileProtectionNone error:&error];
 
-                if (downloadResponse == NO) {
+                if (downloadWriteOK == NO) {
                     // send our results back
-                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:INVALID_URL_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode]];
+                    downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:INVALID_URL_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
                 } else {
                     DLog(@"File Transfer Download success");
 
@@ -479,10 +512,13 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
             }
             @catch(id exception) {
                 // jump back to main thread
-                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsDictionary:[command createFileTransferError:FILE_NOT_FOUND_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode]];
+                downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsDictionary:[command createFileTransferError:FILE_NOT_FOUND_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
             }
         } else {
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode]];
+            downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
         }
     }
 
@@ -494,6 +530,8 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
 
 - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
 {
+    self.mimeType = [response MIMEType];
+
     // required for iOS 4.3, for some reason; response is
     // a plain NSURLResponse, not the HTTP subclass
     if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
@@ -513,7 +551,8 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
 
 - (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
 {
-    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode]];
+    NSString* body = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:body]];
 
     NSLog(@"File Transfer Error: %@", [error localizedDescription]);
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
index 45bf705..14671a5 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
@@ -19,7 +19,6 @@
 
 #import "CDVInAppBrowser.h"
 #import "CDVPluginResult.h"
-#import "CDVViewController.h"
 #import "CDVUserAgentUtil.h"
 
 #define    kInAppBrowserTargetSelf @"_self"
@@ -143,18 +142,7 @@
 
 - (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
 {
-    BOOL passesWhitelist = YES;
-
-    if ([self.viewController isKindOfClass:[CDVViewController class]]) {
-        CDVViewController* vc = (CDVViewController*)self.viewController;
-        if ([vc.whitelist schemeIsAllowed:[url scheme]]) {
-            passesWhitelist = [vc.whitelist URLIsAllowed:url];
-        }
-    } else { // something went wrong, we can't get the whitelist
-        passesWhitelist = NO;
-    }
-
-    if (passesWhitelist) {
+    if ([self.commandDelegate URLIsWhitelisted:url]) {
         NSURLRequest* request = [NSURLRequest requestWithURL:url];
         [self.webView loadRequest:request];
     } else { // this assumes the InAppBrowser can be excepted from the white-list
@@ -374,15 +362,13 @@
 - (void)viewDidUnload
 {
     [self.webView loadHTMLString:nil baseURL:nil];
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
     [super viewDidUnload];
 }
 
 - (void)close
 {
-    if (_userAgentLockToken != 0) {
-        [CDVUserAgentUtil releaseLock:_userAgentLockToken];
-        _userAgentLockToken = 0;
-    }
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
 
     if ([self respondsToSelector:@selector(presentingViewController)]) {
         [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
@@ -398,6 +384,7 @@
 - (void)navigateTo:(NSURL*)url
 {
     NSURLRequest* request = [NSURLRequest requestWithURL:url];
+
     _requestedURL = url;
 
     if (_userAgentLockToken != 0) {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
index e5e3112..cc6613f 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
@@ -22,7 +22,7 @@
 #define kCDVLocalStorageErrorDomain @"kCDVLocalStorageErrorDomain"
 #define kCDVLocalStorageFileOperationError 1
 
-@interface CDVLocalStorage : CDVPlugin <UIWebViewDelegate>
+@interface CDVLocalStorage : CDVPlugin
 
 @property (nonatomic, readonly, strong) NSMutableArray* backupInfo;
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
index 217f611..68175f1 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
@@ -31,21 +31,13 @@
 
 @synthesize backupInfo, webviewDelegate;
 
-- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings
+- (void)pluginInitialize
 {
-    self = (CDVLocalStorage*)[super initWithWebView:theWebView settings:classSettings];
-    if (self) {
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResignActive)
-                                                     name:UIApplicationWillResignActiveNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResignActive)
+                                                 name:UIApplicationWillResignActiveNotification object:nil];
+    BOOL cloudBackup = [@"cloud" isEqualToString:self.commandDelegate.settings[@"BackupWebStorage"]];
 
-        self.backupInfo = [[self class] createBackupInfoWithCloudBackup:[(NSString*)[classSettings objectForKey:@"backupType"] isEqualToString:@"cloud"]];
-
-        // over-ride current webview delegate (for restore reasons)
-        self.webviewDelegate = theWebView.delegate;
-        theWebView.delegate = self;
-    }
-
-    return self;
+    self.backupInfo = [[self class] createBackupInfoWithCloudBackup:cloudBackup];
 }
 
 #pragma mark -
@@ -411,37 +403,9 @@
     [self onResignActive];
 }
 
-#pragma mark -
-#pragma mark UIWebviewDelegate implementation and forwarding
-
-- (void)webViewDidStartLoad:(UIWebView*)theWebView
+- (void)onReset
 {
     [self restore:nil];
-
-    return [self.webviewDelegate webViewDidStartLoad:theWebView];
-}
-
-- (void)webViewDidFinishLoad:(UIWebView*)theWebView
-{
-    return [self.webviewDelegate webViewDidFinishLoad:theWebView];
-}
-
-- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
-{
-    return [self.webviewDelegate webView:theWebView didFailLoadWithError:error];
-}
-
-- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
-{
-    return [self.webviewDelegate webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
-}
-
-#pragma mark -
-#pragma mark Over-rides
-
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];   // this will remove all notification unless added using addObserverForName:object:queue:usingBlock:
 }
 
 @end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
index 9814f35..07af30e 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
@@ -18,7 +18,6 @@
  */
 
 #import "CDVLocation.h"
-#import "CDVViewController.h"
 #import "NSArray+Comparisons.h"
 
 #pragma mark Constants
@@ -477,17 +476,8 @@
 // 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* cdvViewController = (CDVViewController*)self.viewController;
-
-            if ([cdvViewController supportsOrientation:currentOrientation]) {
-                self.locationManager.headingOrientation = (CLDeviceOrientation)currentOrientation;
-                // FYI UIDeviceOrientation and CLDeviceOrientation enums are currently the same
-            }
-        }
-    }
+    // FYI UIDeviceOrientation and CLDeviceOrientation enums are currently the same
+    self.locationManager.headingOrientation = (CLDeviceOrientation)self.viewController.interfaceOrientation;
     self.locationManager.headingFilter = filter;
     [self.locationManager startUpdatingHeading];
     self.headingData.headingStatus = HEADINGSTARTING;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
index 8c59a2b..f5b50eb 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
@@ -23,6 +23,7 @@
 #import "NSMutableArray+QueueAdditions.h"
 #import "CDVCommandDelegate.h"
 
+#define CDVPageDidLoadNotification @"CDVPageDidLoadNotification"
 #define CDVPluginHandleOpenURLNotification @"CDVPluginHandleOpenURLNotification"
 #define CDVPluginResetNotification @"CDVPluginResetNotification"
 #define CDVLocalNotification @"CDVLocalNotification"
@@ -30,14 +31,13 @@
 @interface CDVPlugin : NSObject {}
 
 @property (nonatomic, weak) UIWebView* webView;
-@property (nonatomic, strong) NSDictionary* settings;
 @property (nonatomic, weak) UIViewController* viewController;
 @property (nonatomic, weak) id <CDVCommandDelegate> commandDelegate;
 
 @property (readonly, assign) BOOL hasPendingOperation;
 
-- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings;
 - (CDVPlugin*)initWithWebView:(UIWebView*)theWebView;
+- (void)pluginInitialize;
 
 - (void)handleOpenURL:(NSNotification*)notification;
 - (void)onAppTerminate;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
index 53023c7..a42d241 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
@@ -26,16 +26,12 @@
 @end
 
 @implementation CDVPlugin
-@synthesize webView, settings, viewController, commandDelegate, hasPendingOperation;
+@synthesize webView, viewController, commandDelegate, hasPendingOperation;
 
+// Do not override these methods. Use pluginInitialize instead.
 - (CDVPlugin*)initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings
 {
-    self = [self initWithWebView:theWebView];
-    if (self) {
-        self.settings = classSettings;
-        self.hasPendingOperation = NO;
-    }
-    return self;
+    return [self initWithWebView:theWebView];
 }
 
 - (CDVPlugin*)initWithWebView:(UIWebView*)theWebView
@@ -48,26 +44,29 @@
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReset) name:CDVPluginResetNotification 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
-
-         [[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];
-         
-         // Added in 2.3.0+
-         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveLocalNotification:) name:CDVLocalNotification object:nil]; 
-         
-         */
     }
     return self;
 }
 
+- (void)pluginInitialize
+{
+    // 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
+
+    // [[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];
+
+    // Added in 2.3.0
+    // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveLocalNotification:) name:CDVLocalNotification object:nil];
+
+    // Added in 2.5.0
+    // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad:) name:CDVPageDidLoadNotification object:nil];
+}
+
 - (void)dispose
 {
     viewController = nil;
@@ -140,9 +139,9 @@
 }
 
 // default implementation does nothing, ideally, we are not registered for notification if we aren't going to do anything.
-//- (void)didReceiveLocalNotification:(NSNotification *)notification
-//{    
+// - (void)didReceiveLocalNotification:(NSNotification *)notification
+// {
 //    // UILocalNotification* localNotification = [notification object]; // get the payload as a LocalNotification
-//}
+// }
 
 @end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVSound.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSound.h b/lib/cordova-ios/CordovaLib/Classes/CDVSound.h
index 6551621..8dcf98e 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSound.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSound.h
@@ -98,7 +98,13 @@ typedef NSUInteger CDVMediaMsg;
 - (BOOL)hasAudioSession;
 
 // helper methods
-- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId;
+- (NSURL*)urlForRecording:(NSString*)resourcePath;
+- (NSURL*)urlForPlaying:(NSString*)resourcePath;
+- (NSURL*)urlForResource:(NSString*)resourcePath CDV_DEPRECATED(2.5, "Use specific api for playing or recording");
+
+- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId CDV_DEPRECATED(2.5, "Use updated audioFileForResource api");
+
+- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord;
 - (BOOL)prepareToPlay:(CDVAudioFile*)audioFile withId:(NSString*)mediaId;
 - (NSString*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message;
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSound.m b/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
index e6f729a..99515d7 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
@@ -18,20 +18,18 @@
  */
 
 #import "CDVSound.h"
-#import "CDVViewController.h"
 #import "NSArray+Comparisons.h"
 #import "CDVJSON.h"
 
 #define DOCUMENTS_SCHEME_PREFIX @"documents://"
 #define HTTP_SCHEME_PREFIX @"http://"
 #define HTTPS_SCHEME_PREFIX @"https://"
+#define RECORDING_WAV @"wav"
 
 @implementation CDVSound
 
 @synthesize soundCache, avSession;
 
-// Maps a url for a resource path
-// "Naked" resource paths are assumed to be from the www folder as its base
 - (NSURL*)urlForResource:(NSString*)resourcePath
 {
     NSURL* resourceURL = nil;
@@ -44,7 +42,8 @@
         NSLog(@"Will use resource '%@' from the Internet.", resourcePath);
         resourceURL = [NSURL URLWithString:resourcePath];
     } else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) {
-        filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", [CDVViewController applicationDocumentsDirectory]]];
+        NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
+        filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]];
         NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath);
     } else {
         // attempt to find file path in www directory
@@ -71,9 +70,101 @@
     return resourceURL;
 }
 
-// Creates or gets the cached audio file resource object
+// Maps a url for a resource path for recording
+- (NSURL*)urlForRecording:(NSString*)resourcePath
+{
+    NSURL* resourceURL = nil;
+    NSString* filePath = nil;
+    NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
+
+    // first check for correct extension
+    if ([[resourcePath pathExtension] caseInsensitiveCompare:RECORDING_WAV] != NSOrderedSame) {
+        resourceURL = nil;
+        NSLog(@"Resource for recording must have %@ extension", RECORDING_WAV);
+    } else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) {
+        // try to find Documents:// resources
+        filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]];
+        NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath);
+    } else {
+        // if resourcePath is not from FileSystem put in tmp dir, else attempt to use provided resource path
+        NSString* tmpPath = [NSTemporaryDirectory ()stringByStandardizingPath];
+        BOOL isTmp = [resourcePath rangeOfString:tmpPath].location != NSNotFound;
+        BOOL isDoc = [resourcePath rangeOfString:docsPath].location != NSNotFound;
+        if (!isTmp && !isDoc) {
+            // put in temp dir
+            filePath = [NSString stringWithFormat:@"%@/%@", tmpPath, resourcePath];
+        } else {
+            filePath = resourcePath;
+        }
+    }
+
+    if (filePath != nil) {
+        // create resourceURL
+        resourceURL = [NSURL fileURLWithPath:filePath];
+    }
+    return resourceURL;
+}
+
+// Maps a url for a resource path for playing
+// "Naked" resource paths are assumed to be from the www folder as its base
+- (NSURL*)urlForPlaying:(NSString*)resourcePath
+{
+    NSURL* resourceURL = nil;
+    NSString* filePath = nil;
+
+    // first try to find HTTP:// or Documents:// resources
+
+    if ([resourcePath hasPrefix:HTTP_SCHEME_PREFIX] || [resourcePath hasPrefix:HTTPS_SCHEME_PREFIX]) {
+        // if it is a http url, use it
+        NSLog(@"Will use resource '%@' from the Internet.", resourcePath);
+        resourceURL = [NSURL URLWithString:resourcePath];
+    } else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) {
+        NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
+        filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]];
+        NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath);
+    } else {
+        // attempt to find file path in www directory or LocalFileSystem.TEMPORARY directory
+        filePath = [self.commandDelegate pathForResource:resourcePath];
+        if (filePath == nil) {
+            // see if this exists in the documents/temp directory from a previous recording
+            NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory ()stringByStandardizingPath], resourcePath];
+            if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) {
+                // inefficient as existence will be checked again below but only way to determine if file exists from previous recording
+                filePath = testPath;
+                NSLog(@"Will attempt to use file resource from LocalFileSystem.TEMPORARY directory");
+            } else {
+                // attempt to use path provided
+                filePath = resourcePath;
+                NSLog(@"Will attempt to use file resource '%@'", filePath);
+            }
+        } else {
+            NSLog(@"Found resource '%@' in the web folder.", filePath);
+        }
+    }
+    // check that file exists for all but HTTP_SHEME_PREFIX
+    if (filePath != nil) {
+        // create resourceURL
+        resourceURL = [NSURL fileURLWithPath:filePath];
+        // try to access file
+        NSFileManager* fMgr = [NSFileManager defaultManager];
+        if (![fMgr fileExistsAtPath:filePath]) {
+            resourceURL = nil;
+            NSLog(@"Unknown resource '%@'", resourcePath);
+        }
+    }
+
+    return resourceURL;
+}
+
 - (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId
 {
+    // will maintain backwards compatibility with original implementation
+    return [self audioFileForResource:resourcePath withId:mediaId doValidation:YES forRecording:NO];
+}
+
+// Creates or gets the cached audio file resource object
+- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord
+{
     BOOL bError = NO;
     CDVMediaError errcode = MEDIA_ERR_NONE_SUPPORTED;
     NSString* errMsg = @"";
@@ -88,31 +179,37 @@
     }
     if (audioFile == nil) {
         // validate resourcePath and create
-
         if ((resourcePath == nil) || ![resourcePath isKindOfClass:[NSString class]] || [resourcePath isEqualToString:@""]) {
             bError = YES;
             errcode = MEDIA_ERR_ABORTED;
             errMsg = @"invalid media src argument";
         } else {
-            resourceURL = [self urlForResource:resourcePath];
+            audioFile = [[CDVAudioFile alloc] init];
+            audioFile.resourcePath = resourcePath;
+            audioFile.resourceURL = nil;  // validate resourceURL when actually play or record
+            [[self soundCache] setObject:audioFile forKey:mediaId];
+        }
+    }
+    if (bValidate && (audioFile.resourceURL == nil)) {
+        if (bRecord) {
+            resourceURL = [self urlForRecording:resourcePath];
+        } else {
+            resourceURL = [self urlForPlaying:resourcePath];
         }
-
         if (resourceURL == nil) {
             bError = YES;
             errcode = MEDIA_ERR_ABORTED;
             errMsg = [NSString stringWithFormat:@"Cannot use audio file from resource '%@'", resourcePath];
-        }
-        if (bError) {
-            // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, errcode];
-            jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
-            [self.commandDelegate evalJs:jsString];
         } else {
-            audioFile = [[CDVAudioFile alloc] init];
-            audioFile.resourcePath = resourcePath;
             audioFile.resourceURL = resourceURL;
-            [[self soundCache] setObject:audioFile forKey:mediaId];
         }
     }
+
+    if (bError) {
+        jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
+        [self.commandDelegate evalJs:jsString];
+    }
+
     return audioFile;
 }
 
@@ -150,7 +247,7 @@
     NSString* mediaId = [command.arguments objectAtIndex:0];
     NSString* resourcePath = [command.arguments objectAtIndex:1];
 
-    CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId];
+    CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:NO forRecording:NO];
 
     if (audioFile == nil) {
         NSString* errorMessage = [NSString stringWithFormat:@"Failed to initialize Media file with path %@", resourcePath];
@@ -194,9 +291,8 @@
     BOOL bError = NO;
     NSString* jsString = nil;
 
-    CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId];
-
-    if (audioFile != nil) {
+    CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:YES forRecording:NO];
+    if ((audioFile != nil) && (audioFile.resourceURL != nil)) {
         if (audioFile.player == nil) {
             bError = [self prepareToPlay:audioFile withId:mediaId];
         }
@@ -275,7 +371,12 @@
     if ([resourceURL isFileURL]) {
         audioFile.player = [[CDVAudioPlayer alloc] initWithContentsOfURL:resourceURL error:&playerError];
     } else {
-        NSURLRequest* request = [NSURLRequest requestWithURL:resourceURL];
+        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:resourceURL];
+        NSString* userAgent = [self.commandDelegate userAgent];
+        if (userAgent) {
+            [request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
+        }
+
         NSURLResponse* __autoreleasing response = nil;
         NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&playerError];
         if (playerError) {
@@ -412,11 +513,11 @@
 #pragma unused(callbackId)
 
     NSString* mediaId = [command.arguments objectAtIndex:0];
-    CDVAudioFile* audioFile = [self audioFileForResource:[command.arguments objectAtIndex:1] withId:mediaId];
+    CDVAudioFile* audioFile = [self audioFileForResource:[command.arguments objectAtIndex:1] withId:mediaId doValidation:YES forRecording:YES];
     NSString* jsString = nil;
     NSString* errorMsg = @"";
 
-    if (audioFile != nil) {
+    if ((audioFile != nil) && (audioFile.resourceURL != nil)) {
         NSError* __autoreleasing error = nil;
 
         if (audioFile.recorder != nil) {
@@ -463,9 +564,9 @@
             jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
         }
     } else {
-        // file does not exist
-        NSLog(@"Could not start recording audio, file '%@' does not exist.", audioFile.resourcePath);
-        jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:@"File to record to does not exist"]];
+        // file did not validate
+        NSString* errorMsg = [NSString stringWithFormat:@"Could not record audio at '%@'", audioFile.resourcePath];
+        jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
     }
     if (jsString) {
         [self.commandDelegate evalJs:jsString];

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
index b0d8615..a0868a0 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
@@ -20,7 +20,11 @@
 #import <Foundation/Foundation.h>
 #import "CDVPlugin.h"
 
-@interface CDVSplashScreen : CDVPlugin {}
+@interface CDVSplashScreen : CDVPlugin {
+    UIActivityIndicatorView* _activityView;
+    UIImageView* _imageView;
+    UIView* _parentView;
+}
 
 - (void)show:(CDVInvokedUrlCommand*)command;
 - (void)hide:(CDVInvokedUrlCommand*)command;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
index 2512328..cba1b53 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
@@ -18,32 +18,157 @@
  */
 
 #import "CDVSplashScreen.h"
-#import "CDVViewController.h"
+
+#define kSplashScreenStateShow 0
+#define kSplashScreenStateHide 1
+
+#define kSplashScreenDurationDefault 0.25f
 
 @implementation CDVSplashScreen
 
-- (void)__show:(BOOL)show
+- (void)pluginInitialize
 {
-    // Legacy support - once deprecated classes removed, clean this up
-    id <UIApplicationDelegate> delegate = [[UIApplication sharedApplication] delegate];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
 
-    if ([delegate respondsToSelector:@selector(viewController)]) {
-        id vc = [delegate performSelector:@selector(viewController)];
-        if ([vc isKindOfClass:[CDVViewController class]]) {
-            ((CDVViewController*)vc).imageView.hidden = !show;
-            ((CDVViewController*)vc).activityView.hidden = !show;
-        }
-    }
+    [self show:nil];
 }
 
 - (void)show:(CDVInvokedUrlCommand*)command
 {
-    [self __show:YES];
+    [self updateSplashScreenWithState:kSplashScreenStateShow];
 }
 
 - (void)hide:(CDVInvokedUrlCommand*)command
 {
-    [self __show:NO];
+    [self updateSplashScreenWithState:kSplashScreenStateHide];
+}
+
+- (void)pageDidLoad
+{
+    id autoHideSplashScreenValue = [self.commandDelegate.settings objectForKey:@"AutoHideSplashScreen"];
+
+    // if value is missing, default to yes
+    if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) {
+        [self hide:nil];
+    }
+}
+
+- (void)onOrientationWillChange:(NSNotification*)notification
+{
+    if (_imageView != nil) {
+        UIInterfaceOrientation orientation = [notification.userInfo[UIApplicationStatusBarOrientationUserInfoKey] intValue];
+        [self updateSplashImageForOrientation:orientation];
+    }
+}
+
+- (void)createViews
+{
+    /*
+     * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
+     *
+     *     whiteLarge = UIActivityIndicatorViewStyleWhiteLarge
+     *     white      = UIActivityIndicatorViewStyleWhite
+     *     gray       = UIActivityIndicatorViewStyleGray
+     *
+     */
+    NSString* topActivityIndicator = [self.commandDelegate.settings objectForKey:@"TopActivityIndicator"];
+    UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
+
+    if ([topActivityIndicator isEqualToString:@"whiteLarge"]) {
+        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;
+    } else if ([topActivityIndicator isEqualToString:@"white"]) {
+        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;
+    } else if ([topActivityIndicator isEqualToString:@"gray"]) {
+        topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
+    }
+
+    _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle];
+    _activityView.tag = 2;
+    _activityView.center = self.viewController.view.center;
+    [_activityView startAnimating];
+
+    _imageView = [[UIImageView alloc] init];
+    [self.viewController.view addSubview:_imageView];
+    [self.viewController.view.superview addSubview:_activityView];
+    [self.viewController.view.superview layoutSubviews];
+}
+
+- (void)updateSplashImageForOrientation:(UIInterfaceOrientation)orientation
+{
+    // IPHONE (default)
+    NSString* imageName = @"Default";
+
+    if (CDV_IsIPhone5()) {
+        imageName = [imageName stringByAppendingString:@"-568h"];
+    } else if (CDV_IsIPad()) {
+        // set default to portrait upside down
+        imageName = @"Default-Portrait"; // @"Default-PortraitUpsideDown.png";
+
+        if (orientation == UIInterfaceOrientationLandscapeLeft) {
+            imageName = @"Default-Landscape.png"; // @"Default-LandscapeLeft.png";
+        } else if (orientation == UIInterfaceOrientationLandscapeRight) {
+            imageName = @"Default-Landscape.png"; // @"Default-LandscapeRight.png";
+        }
+    }
+
+    _imageView.image = [UIImage imageNamed:imageName];
+    _imageView.frame = CGRectMake(0, 0, _imageView.image.size.width, _imageView.image.size.height);
+}
+
+- (void)updateSplashScreenWithState:(int)state
+{
+    float toAlpha = state == kSplashScreenStateShow ? 1.0f : 0.0f;
+    BOOL hidden = state == kSplashScreenStateShow ? NO : YES;
+
+    id fadeSplashScreenValue = [self.commandDelegate.settings objectForKey:@"FadeSplashScreen"];
+    id fadeSplashScreenDuration = [self.commandDelegate.settings objectForKey:@"FadeSplashScreenDuration"];
+
+    float fadeDuration = fadeSplashScreenDuration == nil ? kSplashScreenDurationDefault : [fadeSplashScreenDuration floatValue];
+
+    if ((fadeSplashScreenValue == nil) || ![fadeSplashScreenValue boolValue]) {
+        fadeDuration = 0;
+    }
+    if (hidden && (_imageView == nil)) {
+        return;
+    } else if (_imageView == nil) {
+        [self createViews];
+        fadeDuration = 0;
+    }
+
+    if (!hidden) {
+        [self updateSplashImageForOrientation:self.viewController.interfaceOrientation];
+    }
+
+    if (fadeDuration == 0) {
+        [_imageView setHidden:hidden];
+        [_activityView setHidden:hidden];
+    } else {
+        if (state == kSplashScreenStateShow) {
+            // reset states
+            [_imageView setHidden:NO];
+            [_activityView setHidden:NO];
+            [_imageView setAlpha:0.0f];
+            [_activityView setAlpha:0.0f];
+        }
+
+        [UIView transitionWithView:self.viewController.view
+                          duration:fadeDuration
+                           options:UIViewAnimationOptionTransitionNone
+                        animations:^(void) {
+                [_imageView setAlpha:toAlpha];
+                [_activityView setAlpha:toAlpha];
+            }
+                        completion:^(BOOL finished) {
+                if (state == kSplashScreenStateHide) {
+                    // Clean-up resources.
+                    [_imageView removeFromSuperview];
+                    [_activityView removeFromSuperview];
+                    _imageView = nil;
+                    _activityView = nil;
+                }
+            }];
+    }
 }
 
 @end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m b/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
index a645288..1959c77 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
@@ -17,14 +17,17 @@
  under the License.
  */
 
+#import <AssetsLibrary/ALAsset.h>
+#import <AssetsLibrary/ALAssetRepresentation.h>
+#import <AssetsLibrary/ALAssetsLibrary.h>
+#import <MobileCoreServices/MobileCoreServices.h>
 #import "CDVURLProtocol.h"
 #import "CDVCommandQueue.h"
 #import "CDVWhitelist.h"
 #import "CDVViewController.h"
+#import "CDVFile.h"
 
 @interface CDVHTTPURLResponse : NSHTTPURLResponse
-- (id)initWithUnauthorizedURL:(NSURL*)url;
-- (id)initWithBlankResponse:(NSURL*)url;
 @property (nonatomic) NSInteger statusCode;
 @end
 
@@ -106,7 +109,9 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
     NSURL* theUrl = [theRequest URL];
     CDVViewController* viewController = viewControllerForRequest(theRequest);
 
-    if (viewController != nil) {
+    if ([[theUrl absoluteString] hasPrefix:kCDVAssetsLibraryPrefix]) {
+        return YES;
+    } else if (viewController != nil) {
         if ([[theUrl path] isEqualToString:@"/!gap_exec"]) {
             NSString* queuedCommandsJSON = [theRequest valueForHTTPHeaderField:@"cmds"];
             NSString* requestId = [theRequest valueForHTTPHeaderField:@"rc"];
@@ -151,21 +156,35 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
     NSURL* url = [[self request] URL];
 
     if ([[url path] isEqualToString:@"/!gap_exec"]) {
-        CDVHTTPURLResponse* response = [[CDVHTTPURLResponse alloc] initWithBlankResponse:url];
-        [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
-        [[self client] URLProtocolDidFinishLoading:self];
+        [self sendResponseWithResponseCode:200 data:nil mimeType:nil];
+        return;
+    } else if ([[url absoluteString] hasPrefix:kCDVAssetsLibraryPrefix]) {
+        ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+            if (asset) {
+                // We have the asset!  Get the data and send it along.
+                ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
+                NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass ((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
+                Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
+                NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
+                NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
+                [self sendResponseWithResponseCode:200 data:data mimeType:MIMEType];
+            } else {
+                // Retrieving the asset failed for some reason.  Send an error.
+                [self sendResponseWithResponseCode:404 data:nil mimeType:nil];
+            }
+        };
+        ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+            // Retrieving the asset failed for some reason.  Send an error.
+            [self sendResponseWithResponseCode:401 data:nil mimeType:nil];
+        };
+
+        ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
+        [assetsLibrary assetForURL:url resultBlock:resultBlock failureBlock:failureBlock];
         return;
     }
 
     NSString* body = [gWhitelist errorStringForURL:url];
-
-    CDVHTTPURLResponse* response = [[CDVHTTPURLResponse alloc] initWithUnauthorizedURL:url];
-
-    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
-
-    [[self client] URLProtocol:self didLoadData:[body dataUsingEncoding:NSASCIIStringEncoding]];
-
-    [[self client] URLProtocolDidFinishLoading:self];
+    [self sendResponseWithResponseCode:401 data:[body dataUsingEncoding:NSASCIIStringEncoding] mimeType:nil];
 }
 
 - (void)stopLoading
@@ -178,29 +197,31 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
     return NO;
 }
 
-@end
-
-@implementation CDVHTTPURLResponse
-@synthesize statusCode;
-
-- (id)initWithUnauthorizedURL:(NSURL*)url
+- (void)sendResponseWithResponseCode:(NSInteger)statusCode data:(NSData*)data mimeType:(NSString*)mimeType
 {
-    self = [super initWithURL:url MIMEType:@"text/plain" expectedContentLength:-1 textEncodingName:@"UTF-8"];
-    if (self) {
-        self.statusCode = 401;
+    if (mimeType == nil) {
+        mimeType = @"text/plain";
     }
-    return self;
-}
+    NSString* encodingName = [@"text/plain" isEqualToString:mimeType] ? @"UTF-8" : nil;
+    CDVHTTPURLResponse* response =
+        [[CDVHTTPURLResponse alloc] initWithURL:[[self request] URL]
+                                       MIMEType:mimeType
+                          expectedContentLength:[data length]
+                               textEncodingName:encodingName];
+    response.statusCode = statusCode;
 
-- (id)initWithBlankResponse:(NSURL*)url
-{
-    self = [super initWithURL:url MIMEType:@"text/plain" expectedContentLength:-1 textEncodingName:@"UTF-8"];
-    if (self) {
-        self.statusCode = 200;
+    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
+    if (data != nil) {
+        [[self client] URLProtocol:self didLoadData:data];
     }
-    return self;
+    [[self client] URLProtocolDidFinishLoading:self];
 }
 
+@end
+
+@implementation CDVHTTPURLResponse
+@synthesize statusCode;
+
 - (NSDictionary*)allHeaderFields
 {
     return nil;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.h b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.h
index 662b674..4de382f 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.h
@@ -22,6 +22,6 @@
 @interface CDVUserAgentUtil : NSObject
 + (NSString*)originalUserAgent;
 + (void)acquireLock:(void (^)(NSInteger lockToken))block;
-+ (void)releaseLock:(NSInteger)lockToken;
++ (void)releaseLock:(NSInteger*)lockToken;
 + (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken;
 @end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
index e2baef0..5c43c51 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
@@ -84,11 +84,14 @@ static NSMutableArray* gPendingSetUserAgentBlocks = nil;
     }
 }
 
-+ (void)releaseLock:(NSInteger)lockToken
++ (void)releaseLock:(NSInteger*)lockToken
 {
-    NSAssert(gCurrentLockToken == lockToken, @"Got token %d, expected %d", lockToken, gCurrentLockToken);
+    if (*lockToken == 0) {
+        return;
+    }
+    NSAssert(gCurrentLockToken == *lockToken, @"Got token %d, expected %d", *lockToken, gCurrentLockToken);
 
-    VerboseLog(@"Released lock %d", lockToken);
+    VerboseLog(@"Released lock %d", *lockToken);
     if ([gPendingSetUserAgentBlocks count] > 0) {
         void (^block)() = [gPendingSetUserAgentBlocks objectAtIndex:0];
         [gPendingSetUserAgentBlocks removeObjectAtIndex:0];
@@ -98,6 +101,7 @@ static NSMutableArray* gPendingSetUserAgentBlocks = nil;
     } else {
         gCurrentLockToken = 0;
     }
+    *lockToken = 0;
 }
 
 + (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
index ed6f7fc..82e22f6 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
@@ -40,14 +40,11 @@
 
 @property (nonatomic, readonly, strong) NSMutableDictionary* pluginObjects;
 @property (nonatomic, readonly, strong) NSDictionary* pluginsMap;
-@property (nonatomic, readonly, strong) NSDictionary* settings;
+@property (nonatomic, readonly, strong) NSMutableDictionary* settings;
 @property (nonatomic, readonly, strong) NSXMLParser* configParser;
 @property (nonatomic, readonly, strong) CDVWhitelist* whitelist; // readonly for public
 @property (nonatomic, readonly, assign) BOOL loadFromString;
-
-@property (nonatomic, readwrite, assign) BOOL useSplashScreen;
-@property (nonatomic, readonly, strong) IBOutlet UIActivityIndicatorView* activityView;
-@property (nonatomic, readonly, strong) UIImageView* imageView;
+@property (nonatomic, readwrite, assign) BOOL useSplashScreen CDV_DEPRECATED(2.5, "Add/Remove the SplashScreen plugin instead of setting this property.");
 
 @property (nonatomic, readwrite, copy) NSString* wwwFolderName;
 @property (nonatomic, readwrite, copy) NSString* startPage;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
index 36ae785..bec716d 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
@@ -23,23 +23,24 @@
 #import "CDVCommandDelegateImpl.h"
 #import "CDVConfigParser.h"
 #import "CDVUserAgentUtil.h"
+#import "CDVWebViewDelegate.h"
 
 #define degreesToRadian(x) (M_PI * (x) / 180.0)
 
 @interface CDVViewController () {
     NSInteger _userAgentLockToken;
+    CDVWebViewDelegate* _webViewDelegate;
 }
 
 @property (nonatomic, readwrite, strong) NSXMLParser* configParser;
-@property (nonatomic, readwrite, strong) NSDictionary* settings;
+@property (nonatomic, readwrite, strong) NSMutableDictionary* settings;
 @property (nonatomic, readwrite, strong) CDVWhitelist* whitelist;
 @property (nonatomic, readwrite, strong) NSMutableDictionary* pluginObjects;
+@property (nonatomic, readwrite, strong) NSArray* startupPluginNames;
 @property (nonatomic, readwrite, strong) NSDictionary* pluginsMap;
 @property (nonatomic, readwrite, strong) NSArray* supportedOrientations;
 @property (nonatomic, readwrite, assign) BOOL loadFromString;
 
-@property (nonatomic, readwrite, strong) IBOutlet UIActivityIndicatorView* activityView;
-@property (nonatomic, readwrite, strong) UIImageView* imageView;
 @property (readwrite, assign) BOOL initialized;
 
 @property (atomic, strong) NSURL* openURL;
@@ -49,9 +50,9 @@
 @implementation CDVViewController
 
 @synthesize webView, supportedOrientations;
-@synthesize pluginObjects, pluginsMap, whitelist;
+@synthesize pluginObjects, pluginsMap, whitelist, startupPluginNames;
 @synthesize configParser, settings, loadFromString;
-@synthesize imageView, activityView, useSplashScreen;
+@synthesize useSplashScreen;
 @synthesize wwwFolderName, startPage, initialized, openURL;
 @synthesize commandDelegate = _commandDelegate;
 @synthesize commandQueue = _commandQueue;
@@ -61,9 +62,6 @@
     if ((self != nil) && !self.initialized) {
         _commandQueue = [[CDVCommandQueue alloc] initWithViewController:self];
         _commandDelegate = [[CDVCommandDelegateImpl alloc] initWithViewController:self];
-        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedOrientationChange)
-                                                     name:UIDeviceOrientationDidChangeNotification object:nil];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppWillTerminate:)
                                                      name:UIApplicationWillTerminateNotification object:nil];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppWillResignActive:)
@@ -87,6 +85,7 @@
 
         // load config.xml settings
         [self loadSettings];
+        useSplashScreen = YES;
     }
 }
 
@@ -162,16 +161,20 @@
     [configParser parse];
 
     // Get the plugin dictionary, whitelist and settings from the delegate.
-    self.pluginsMap = [delegate.pluginsDict dictionaryWithLowercaseKeys];
+    self.pluginsMap = delegate.pluginsDict;
+    self.startupPluginNames = delegate.startupPluginNames;
     self.whitelist = [[CDVWhitelist alloc] initWithArray:delegate.whitelistHosts];
     self.settings = delegate.settings;
 
     // And the start folder/page.
     self.wwwFolderName = @"www";
-    self.startPage = [delegate getStartPage];
+    self.startPage = delegate.startPage;
+    if (self.startPage == nil) {
+        self.startPage = @"index.html";
+    }
 
     // Initialize the plugin objects dict.
-    self.pluginObjects = [[NSMutableDictionary alloc] initWithCapacity:4];
+    self.pluginObjects = [[NSMutableDictionary alloc] initWithCapacity:20];
 }
 
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
@@ -202,13 +205,14 @@
 
     NSString* backupWebStorageType = @"cloud"; // default value
 
-    id backupWebStorage = [self.settings objectForKey:@"BackupWebStorage"];
+    id backupWebStorage = self.settings[@"BackupWebStorage"];
     if ([backupWebStorage isKindOfClass:[NSString class]]) {
         backupWebStorageType = backupWebStorage;
     } else if ([backupWebStorage isKindOfClass:[NSNumber class]]) {
         NSLog(@"Deprecated: BackupWebStorage boolean property is a string property now (none, local, cloud). A boolean value of 'true' will be mapped to 'cloud'. Consult the docs: http://docs.cordova.io/en/edge/guide_project-settings_ios_index.md.html#Project%%20Settings%%20for%%20iOS");
         backupWebStorageType = [(NSNumber*) backupWebStorage boolValue] ? @"cloud" : @"none";
     }
+    self.settings[@"BackupWebStorage"] = backupWebStorageType;
 
     if (IsAtLeastiOSVersion(@"5.1")) {
         [CDVLocalStorage __fixupDatabaseLocationsWithBackupType:backupWebStorageType];
@@ -243,8 +247,7 @@
      */
     if (IsAtLeastiOSVersion(@"5.1") && (([backupWebStorageType isEqualToString:@"local"]) ||
             ([backupWebStorageType isEqualToString:@"cloud"] && !IsAtLeastiOSVersion(@"6.0")))) {
-        [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView settings:[NSDictionary dictionaryWithObjectsAndKeys:
-                    @"backupType", backupWebStorageType, nil]] withClassName:NSStringFromClass([CDVLocalStorage class])];
+        [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])];
     }
 
     /*
@@ -304,6 +307,15 @@
         }
     }
 
+    for (NSString* pluginName in self.startupPluginNames) {
+        [self getCommandInstance:pluginName];
+    }
+
+    // TODO: Remove this explicit instantiation once we move to cordova-CLI.
+    if (useSplashScreen) {
+        [self getCommandInstance:@"splashscreen"];
+    }
+
     // /////////////////
     [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) {
             _userAgentLockToken = lockToken;
@@ -441,7 +453,8 @@
         [self.view addSubview:self.webView];
         [self.view sendSubviewToBack:self.webView];
 
-        self.webView.delegate = self;
+        _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];
+        self.webView.delegate = _webViewDelegate;
 
         // register this viewcontroller with the NSURLProtocol, only after the User-Agent is set
         [CDVURLProtocol registerViewController:self];
@@ -480,6 +493,7 @@
 
     self.webView.delegate = nil;
     self.webView = nil;
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
 }
 
 #pragma mark UIWebViewDelegate
@@ -490,33 +504,19 @@
  */
 - (void)webViewDidStartLoad:(UIWebView*)theWebView
 {
+    NSLog(@"Resetting plugins due to page load.");
     [_commandQueue resetRequestId];
-    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginResetNotification object:nil]];
+    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginResetNotification object:self.webView]];
 }
 
 /**
- Called when the webview finishes loading.  This stops the activity view and closes the imageview
+ Called when the webview finishes loading.  This stops the activity view.
  */
 - (void)webViewDidFinishLoad:(UIWebView*)theWebView
 {
-    if (_userAgentLockToken != 0) {
-        [CDVUserAgentUtil releaseLock:_userAgentLockToken];
-        _userAgentLockToken = 0;
-    }
-
-    /*
-     * Hide the Top Activity THROBBER in the Battery Bar
-     */
-    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
-
-    id autoHideSplashScreenValue = [self.settings objectForKey:@"AutoHideSplashScreen"];
-    // if value is missing, default to yes
-    if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) {
-        self.imageView.hidden = YES;
-        self.activityView.hidden = YES;
-        [self.view.superview bringSubviewToFront:self.webView];
-    }
-    [self didRotateFromInterfaceOrientation:(UIInterfaceOrientation)[[UIDevice currentDevice] orientation]];
+    NSLog(@"Finished load of: %@", theWebView.request.URL);
+    // It's safe to release the lock even if this is just a sub-frame that's finished loading.
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
 
     // The .onNativeReady().fire() will work when cordova.js is already loaded.
     // The _nativeReady = true; is used when this is run before cordova.js is loaded.
@@ -524,22 +524,21 @@
     // Don't use [commandDelegate evalJs] here since it relies on cordova.js being loaded already.
     [self.webView stringByEvaluatingJavaScriptFromString:nativeReady];
 
+    /*
+     * Hide the Top Activity THROBBER in the Battery Bar
+     */
+    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+
     [self processOpenUrl];
+
+    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:nil]];
 }
 
-- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error
+- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
 {
-    if (_userAgentLockToken != 0) {
-        [CDVUserAgentUtil releaseLock:_userAgentLockToken];
-        _userAgentLockToken = 0;
-    }
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
 
     NSLog(@"Failed to load webpage with error: %@", [error localizedDescription]);
-
-    /*
-     if ([error code] != NSURLErrorCancelled)
-     alert([error localizedDescription]);
-     */
 }
 
 - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
@@ -595,8 +594,6 @@
      * Handle all other types of urls (tel:, sms:), and requests to load a url in the main webview.
      */
     else {
-        // BOOL isIFrame = ([theWebView.request.mainDocumentURL absoluteString] == nil);
-
         if ([self.whitelist schemeIsAllowed:[url scheme]]) {
             return [self.whitelist URLIsAllowed:url];
         } else {
@@ -647,131 +644,6 @@
     return basePath;
 }
 
-- (void)showSplashScreen
-{
-    CGRect screenBounds = [[UIScreen mainScreen] bounds];
-    NSString* launchImageFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchImageFile"];
-
-    if (launchImageFile == nil) { // fallback if no launch image was specified
-        if (CDV_IsIPhone5()) {
-            // iPhone 5 or iPod Touch 6th-gen
-            launchImageFile = @"Default-568h";
-        } else {
-            launchImageFile = @"Default";
-        }
-    }
-
-    NSString* orientedLaunchImageFile = nil;
-    CGAffineTransform startupImageTransform = CGAffineTransformIdentity;
-    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
-    CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
-    UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
-    UIImage* launchImage = nil;
-
-    // default to center of screen as in the original implementation. This will produce the 20px jump
-    CGPoint center = CGPointMake((screenBounds.size.width / 2), (screenBounds.size.height / 2));
-
-    if (CDV_IsIPad()) {
-        if (!UIDeviceOrientationIsValidInterfaceOrientation(deviceOrientation)) {
-            deviceOrientation = (UIDeviceOrientation)statusBarOrientation;
-        }
-
-        switch (deviceOrientation) {
-            case UIDeviceOrientationLandscapeLeft: // this is where the home button is on the right (yeah, I know, confusing)
-                {
-                    orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
-                    startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(90));
-                    center.x -= MIN(statusBarFrame.size.width, statusBarFrame.size.height) / 2;
-                }
-                break;
-
-            case UIDeviceOrientationLandscapeRight: // this is where the home button is on the left (yeah, I know, confusing)
-                {
-                    orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Landscape", launchImageFile];
-                    startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(-90));
-                    center.x += MIN(statusBarFrame.size.width, statusBarFrame.size.height) / 2;
-                }
-                break;
-
-            case UIDeviceOrientationPortraitUpsideDown:
-                {
-                    orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
-                    startupImageTransform = CGAffineTransformMakeRotation(degreesToRadian(180));
-                    center.y -= MIN(statusBarFrame.size.width, statusBarFrame.size.height) / 2;
-                }
-                break;
-
-            case UIDeviceOrientationPortrait:
-            default:
-                {
-                    orientedLaunchImageFile = [NSString stringWithFormat:@"%@-Portrait", launchImageFile];
-                    startupImageTransform = CGAffineTransformIdentity;
-                    center.y += MIN(statusBarFrame.size.width, statusBarFrame.size.height) / 2;
-                }
-                break;
-        }
-    } else { // not iPad
-        orientedLaunchImageFile = launchImageFile;
-    }
-
-    launchImage = [UIImage imageNamed:[[self class] resolveImageResource:orientedLaunchImageFile]];
-    if (launchImage == nil) {
-        NSLog(@"WARNING: Splash-screen image '%@' was not found. Orientation: %d, iPad: %d", orientedLaunchImageFile, deviceOrientation, CDV_IsIPad());
-    }
-
-    self.imageView = [[UIImageView alloc] initWithImage:launchImage];
-    self.imageView.tag = 1;
-    self.imageView.center = center;
-
-    self.imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin);
-    [self.imageView setTransform:startupImageTransform];
-    [self.view.superview addSubview:self.imageView];
-
-    /*
-     * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
-     *
-     *     whiteLarge = UIActivityIndicatorViewStyleWhiteLarge
-     *     white      = UIActivityIndicatorViewStyleWhite
-     *     gray       = UIActivityIndicatorViewStyleGray
-     *
-     */
-    NSString* topActivityIndicator = [self.settings objectForKey:@"TopActivityIndicator"];
-    UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
-
-    if ([topActivityIndicator isEqualToString:@"whiteLarge"]) {
-        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;
-    } else if ([topActivityIndicator isEqualToString:@"white"]) {
-        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;
-    } else if ([topActivityIndicator isEqualToString:@"gray"]) {
-        topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
-    }
-
-    self.activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle];
-    self.activityView.tag = 2;
-
-    id showSplashScreenSpinnerValue = [self.settings objectForKey:@"ShowSplashScreenSpinner"];
-    // backwards compatibility - if key is missing, default to true
-    if ((showSplashScreenSpinnerValue == nil) || [showSplashScreenSpinnerValue boolValue]) {
-        [self.view.superview addSubview:self.activityView];
-    }
-
-    self.activityView.center = self.view.center;
-    [self.activityView startAnimating];
-
-    [self.view.superview layoutSubviews];
-}
-
-BOOL gSplashScreenShown = NO;
-- (void)receivedOrientationChange
-{
-    if (self.imageView == nil) {
-        gSplashScreenShown = YES;
-        if (self.useSplashScreen) {
-            [self showSplashScreen];
-        }
-    }
-}
-
 #pragma mark CordovaCommands
 
 - (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className
@@ -785,6 +657,7 @@ BOOL gSplashScreenShown = NO;
     }
 
     [self.pluginObjects setObject:plugin forKey:className];
+    [plugin pluginInitialize];
 }
 
 /**
@@ -805,16 +678,9 @@ BOOL gSplashScreenShown = NO;
 
     id obj = [self.pluginObjects objectForKey:className];
     if (!obj) {
-        // attempt to load the settings for this command class
-        NSDictionary* classSettings = [self.settings objectForKey:className];
+        obj = [[NSClassFromString (className)alloc] initWithWebView:webView];
 
-        if (classSettings) {
-            obj = [[NSClassFromString (className)alloc] initWithWebView:webView settings:classSettings];
-        } else {
-            obj = [[NSClassFromString (className)alloc] initWithWebView:webView];
-        }
-
-        if ((obj != nil) && [obj isKindOfClass:[CDVPlugin class]]) {
+        if (obj != nil) {
             [self registerPlugin:obj withClassName:className];
         } else {
             NSLog(@"CDVPlugin class %@ (pluginName: %@) does not exist.", className, pluginName);
@@ -955,9 +821,9 @@ BOOL gSplashScreenShown = NO;
     [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
     [[NSNotificationCenter defaultCenter] removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
     [[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPluginHandleOpenURLNotification object:nil];
-
     self.webView.delegate = nil;
     self.webView = nil;
+    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
     [_commandQueue dispose];
     [[self.pluginObjects allValues] makeObjectsPerformSelector:@selector(dispose)];
 }

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.h b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.h
new file mode 100644
index 0000000..8a89a22
--- /dev/null
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.h
@@ -0,0 +1,37 @@
+/*
+ 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>
+
+/**
+ * Distinguishes top-level navigations from sub-frame navigations.
+ * shouldStartLoadWithRequest is called for every request, but didStartLoad
+ * and didFinishLoad is called only for top-level navigations.
+ * Relevant bug: CB-2389
+ */
+@interface CDVWebViewDelegate : NSObject <UIWebViewDelegate>{
+    __weak NSObject <UIWebViewDelegate>* _delegate;
+    NSInteger _loadCount;
+    NSInteger _state;
+    NSInteger _curLoadToken;
+}
+
+- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate;
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
new file mode 100644
index 0000000..9ee8186
--- /dev/null
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
@@ -0,0 +1,157 @@
+/*
+ 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 "CDVWebViewDelegate.h"
+#import "CDVAvailability.h"
+
+typedef enum {
+    STATE_NORMAL,
+    STATE_SHOULD_LOAD_MISSING,
+    STATE_WAITING_FOR_START,
+    STATE_WAITING_FOR_FINISH
+} State;
+
+@implementation CDVWebViewDelegate
+
+- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate
+{
+    self = [super init];
+    if (self != nil) {
+        _delegate = delegate;
+        _loadCount = -1;
+        _state = STATE_NORMAL;
+    }
+    return self;
+}
+
+- (BOOL)isPageLoaded:(UIWebView*)webView
+{
+    NSString* readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];
+
+    return [readyState isEqualToString:@"loaded"] || [readyState isEqualToString:@"complete"];
+}
+
+- (BOOL)isJsLoadTokenSet:(UIWebView*)webView
+{
+    NSString* loadToken = [webView stringByEvaluatingJavaScriptFromString:@"window.__cordovaLoadToken"];
+
+    return [[NSString stringWithFormat:@"%d", _curLoadToken] isEqualToString:loadToken];
+}
+
+- (void)setLoadToken:(UIWebView*)webView
+{
+    _curLoadToken += 1;
+    [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.__cordovaLoadToken=%d", _curLoadToken]];
+}
+
+- (void)pollForPageLoadStart:(UIWebView*)webView
+{
+    if ((_state != STATE_WAITING_FOR_START) && (_state != STATE_SHOULD_LOAD_MISSING)) {
+        return;
+    }
+    if (![self isJsLoadTokenSet:webView]) {
+        _state = STATE_WAITING_FOR_FINISH;
+        [self setLoadToken:webView];
+        [_delegate webViewDidStartLoad:webView];
+        [self pollForPageLoadFinish:webView];
+    }
+}
+
+- (void)pollForPageLoadFinish:(UIWebView*)webView
+{
+    if (_state != STATE_WAITING_FOR_FINISH) {
+        return;
+    }
+    if ([self isPageLoaded:webView]) {
+        _state = STATE_SHOULD_LOAD_MISSING;
+        [_delegate webViewDidFinishLoad:webView];
+    } else {
+        [self performSelector:@selector(pollForPageLoaded) withObject:webView afterDelay:50];
+    }
+}
+
+- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
+{
+    BOOL shouldLoad = [_delegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+
+    if (shouldLoad) {
+        BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];
+        if (isTopLevelNavigation) {
+            _loadCount = 0;
+            _state = STATE_NORMAL;
+        }
+    }
+    return shouldLoad;
+}
+
+- (void)webViewDidStartLoad:(UIWebView*)webView
+{
+    if (_state == STATE_NORMAL) {
+        if (_loadCount == 0) {
+            [_delegate webViewDidStartLoad:webView];
+            _loadCount += 1;
+        } else if (_loadCount > 0) {
+            _loadCount += 1;
+        } else if (!IsAtLeastiOSVersion(@"6.0")) {
+            // If history.go(-1) is used pre-iOS6, the shouldStartLoadWithRequest function is not called.
+            // Without shouldLoad, we can't distinguish an iframe from a top-level navigation.
+            // We could try to distinguish using [UIWebView canGoForward], but that's too much complexity,
+            // and would work only on the first time it was used.
+
+            // Our work-around is to set a JS variable and poll until it disappears (from a naviagtion).
+            _state = STATE_WAITING_FOR_START;
+            [self setLoadToken:webView];
+        }
+    } else {
+        [self pollForPageLoadStart:webView];
+        [self pollForPageLoadFinish:webView];
+    }
+}
+
+- (void)webViewDidFinishLoad:(UIWebView*)webView
+{
+    if (_state == STATE_NORMAL) {
+        if (_loadCount == 1) {
+            [_delegate webViewDidFinishLoad:webView];
+            _loadCount -= 1;
+        } else if (_loadCount > 1) {
+            _loadCount -= 1;
+        }
+    } else {
+        [self pollForPageLoadStart:webView];
+        [self pollForPageLoadFinish:webView];
+    }
+}
+
+- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error
+{
+    if (_state == STATE_NORMAL) {
+        if (_loadCount == 1) {
+            [_delegate webView:webView didFailLoadWithError:error];
+            _loadCount -= 1;
+        } else if (_loadCount > 1) {
+            _loadCount -= 1;
+        }
+    } else {
+        [self pollForPageLoadStart:webView];
+        [self pollForPageLoadFinish:webView];
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
index 53d2d23..4868020 100644
--- a/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
+++ b/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
@@ -84,6 +84,8 @@
 		EB96673C16A8970A00D86CDF /* CDVUserAgentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = EB96673A16A8970900D86CDF /* CDVUserAgentUtil.m */; };
 		EBA3557315ABD38C00F4DE24 /* NSArray+Comparisons.h in Headers */ = {isa = PBXBuildFile; fileRef = EBA3557115ABD38C00F4DE24 /* NSArray+Comparisons.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		EBA3557515ABD38C00F4DE24 /* NSArray+Comparisons.m in Sources */ = {isa = PBXBuildFile; fileRef = EBA3557215ABD38C00F4DE24 /* NSArray+Comparisons.m */; };
+		EBFF4DBC16D3FE2E008F452B /* CDVWebViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EBFF4DBA16D3FE2E008F452B /* CDVWebViewDelegate.m */; };
+		EBFF4DBD16D3FE2E008F452B /* CDVWebViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = EBFF4DBB16D3FE2E008F452B /* CDVWebViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F858FBC6166009A8007DA594 /* CDVConfigParser.h in Headers */ = {isa = PBXBuildFile; fileRef = F858FBC4166009A8007DA594 /* CDVConfigParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F858FBC7166009A8007DA594 /* CDVConfigParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F858FBC5166009A8007DA594 /* CDVConfigParser.m */; };
 /* End PBXBuildFile section */
@@ -180,6 +182,8 @@
 		EB96673A16A8970900D86CDF /* CDVUserAgentUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVUserAgentUtil.m; path = Classes/CDVUserAgentUtil.m; sourceTree = "<group>"; };
 		EBA3557115ABD38C00F4DE24 /* NSArray+Comparisons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+Comparisons.h"; path = "Classes/NSArray+Comparisons.h"; sourceTree = "<group>"; };
 		EBA3557215ABD38C00F4DE24 /* NSArray+Comparisons.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+Comparisons.m"; path = "Classes/NSArray+Comparisons.m"; sourceTree = "<group>"; };
+		EBFF4DBA16D3FE2E008F452B /* CDVWebViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVWebViewDelegate.m; path = Classes/CDVWebViewDelegate.m; sourceTree = "<group>"; };
+		EBFF4DBB16D3FE2E008F452B /* CDVWebViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVWebViewDelegate.h; path = Classes/CDVWebViewDelegate.h; sourceTree = "<group>"; };
 		F858FBC4166009A8007DA594 /* CDVConfigParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVConfigParser.h; path = Classes/CDVConfigParser.h; sourceTree = "<group>"; };
 		F858FBC5166009A8007DA594 /* CDVConfigParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVConfigParser.m; path = Classes/CDVConfigParser.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -257,6 +261,8 @@
 		888700D710922F56009987E8 /* Commands */ = {
 			isa = PBXGroup;
 			children = (
+				EBFF4DBA16D3FE2E008F452B /* CDVWebViewDelegate.m */,
+				EBFF4DBB16D3FE2E008F452B /* CDVWebViewDelegate.h */,
 				30C5F1DD15AF9E950052A00D /* CDVDevice.h */,
 				30C5F1DE15AF9E950052A00D /* CDVDevice.m */,
 				301F2F2914F3C9CA003FE9FC /* CDV.h */,
@@ -399,6 +405,7 @@
 				3073E9ED1656D51200957977 /* CDVScreenOrientationDelegate.h in Headers */,
 				F858FBC6166009A8007DA594 /* CDVConfigParser.h in Headers */,
 				30F3930B169F839700B22307 /* CDVJSON.h in Headers */,
+				EBFF4DBD16D3FE2E008F452B /* CDVWebViewDelegate.h in Headers */,
 				EB96673B16A8970A00D86CDF /* CDVUserAgentUtil.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -429,7 +436,7 @@
 		0867D690FE84028FC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0430;
+				LastUpgradeCheck = 0460;
 			};
 			buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "CordovaLib" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -494,6 +501,7 @@
 				F858FBC7166009A8007DA594 /* CDVConfigParser.m in Sources */,
 				30F3930C169F839700B22307 /* CDVJSON.m in Sources */,
 				EB96673C16A8970A00D86CDF /* CDVUserAgentUtil.m in Sources */,
+				EBFF4DBC16D3FE2E008F452B /* CDVWebViewDelegate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -564,12 +572,17 @@
 					armv7s,
 				);
 				"ARCHS[sdk=iphonesimulator*]" = i386;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				GCC_THUMB_SUPPORT = NO;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 4.3;
 				ONLY_ACTIVE_ARCH = NO;
@@ -592,11 +605,16 @@
 					armv7s,
 				);
 				"ARCHS[sdk=iphonesimulator*]" = i386;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				GCC_THUMB_SUPPORT = NO;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 4.3;
 				ONLY_ACTIVE_ARCH = NO;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-ios/CordovaLib/VERSION
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/VERSION b/lib/cordova-ios/CordovaLib/VERSION
index 197c4d5..aa0822f 100644
--- a/lib/cordova-ios/CordovaLib/VERSION
+++ b/lib/cordova-ios/CordovaLib/VERSION
@@ -1 +1 @@
-2.4.0
+2.5.0rc1