Upgrading the PhoneGap Library Used By the iOS Hybrid Web Container

SAP Mobile Platform includes the Cordova 2.0 libraries. Follow these steps if you want to upgrade the iOS Hybrid Web Container to a more recent version of the Cordova library.

The Cordova library used by the Hybrid Web Container uses source code that has been modified from the original source, primarily because the original source does not support some Hybrid Web Container features. This procedure describes upgrading the Cordova library from version 2.0.0 to version 2.9.0. The steps to upgrade to other versions differ slightly. Since the Hybrid Web Container template project does not include the source code for building HWCLib.a, the ability to upgrade Cordova to newer versions is limited, and certain new Cordova features may not work properly in Hybrid Web Container project.
Note: Upgrading the Hybrid Web Container container to use Cordova 3.0.0 is not supported because the Hybrid Web Container project does not work with Cordova 3.0.0 CLI.
  1. From a browser on your Mac, download phonegap 2.9.0 from phonegap.com, and unzip it to a local folder.
  2. Open terminal app, go to the unzipped folder phonegap-2.9.0/lib/ios/bin, and create a Cordova prototype project using this command:
    $ bash create /<path>/hello hello.example.com hello
  3. From Xcode, open the generated project hello/hello.xcodeproj.
    The cordovalib project will be used to update the Hybrid Web Container (HWC) project.
  4. Open the HWC template project. In the HWC project's build setting, “Linking\Other Link Flag” section, delete all references to cordovalib.a.
  5. From Finder, delete the Cordova folder under the HWC template project folder. Delete all cordovalib.a files from the HWC project's lib folder.
  6. In the XCode HWC project, add the cordovalib project created in the hello project as a dependent project. Update the HWC project's setting to include the cordova project in the HWC’s “Target Dependencies” and “Link Binary With Libraries” section.
  7. In the HWC Xcode Project Navigator, find and open the CDVViewController.h file located in the Classes/Cleaver group folder.
  8. Add a UIViewController property declaration:
    @property (nonatomic, strong) UIViewController* viewController; 
  9. Find and remove the declaration of the createGapView function in CDVViewController.h:
    -(void) createGapView; 
  10. Add these function declarations in CDVViewController:
    -(void)setTheWebView: (UIWebView*) theWebView; 
    -(void)setTheViewController: (UIViewController*) theViewController; 
  11. In the Xcode Project Navigator, find and open the CDVViewController.m file, synthesizing the viewController property:
    @synthesize viewController = _viewController; 
  12. Use #if 0 to comment out these portions of the viewDidLoad function in the CDVViewController.m file:
    #if 0
        NSURL* appURL = nil;
        NSString* loadErr = nil;
    
        if ([self.startPage rangeOfString:@"://"].location != NSNotFound) {
            appURL = [NSURL URLWithString:self.startPage];
        } else if ([self.wwwFolderName rangeOfString:@"://"].location != NSNotFound) {
            appURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", self.wwwFolderName, self.startPage]];
        } else {
            NSString* startFilePath = [self.commandDelegate pathForResource:self.startPage];
            if (startFilePath == nil) {
                loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage];
                NSLog(@"%@", loadErr);
                self.loadFromString = YES;
                appURL = nil;
            } else {
                appURL = [NSURL fileURLWithPath:startFilePath];
            }
    }
    #endif 
    …
    
    #if 0
        // // Instantiate the WebView ///////////////
    
        [self createGapView];
    
        // /////////////////
    #endif
    
    …
    
    #if 0
            if (!loadErr) {
                NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
                [self.webView loadRequest:appReq];
            } else {
                NSString* html = [NSString stringWithFormat:@" %@ ", loadErr];
                [self.webView loadHTMLString:html baseURL:nil];
            }
    #endif
    
  13. Update the two registerPlugin functions in the CDVViewController.m file by replacing:
    [plugin setViewController:self];
    with
     [plugin setViewController: self.viewController];
  14. Add the implementations for the two new methods mentioned previously in the CDVViewController.m file:
    -(void) setTheWebView: (UIWebView*) theWebView { 
    self.webView = theWebView; 
    } 
    
    -(void) setTheViewController: (UIViewController *)theViewController { 
    self.viewController = (CDVViewController*)theViewController; 
    }
  15. Add this line to the dealloc function in the CDVViewController.m file:
    self.whitelist = nil;
  16. Delete the CreateGapView function implementation from the CDVViewController.m file.
  17. In the Xcode Project Navigator, find and open the CDVPlugin.m file, which is in the Classes/Commands group folder, and add this code at the very top of the dealloc function:
    self.viewController = nil;
  18. At the beginning of initializeAppAfterKeyVaultUnlocked method in the HWCAppDelegate.m file, call:
    [super viewDidLoad]; 
  19. Add Jsonkit back into the new Cordova library to avoid link errors. You can copy the jsonkit.h and jsonkit.m files from the PhoneGap 2.0.0 library project.
    Beginning with Cordova 2.4.0, the JsonKit is no longer included in cordova library, however, HWCLib.a uses some functions provided by Jsonkit.
  20. Add Jsonkit.h and Jsonkit.m as source files in the Cordova library project.
  21. Set the compile flag “-fno-objc-arc” for the jsonkit.m file in the “build phase”/”compile source” section.
    The new cordova library project is compiled with ARC enabled, but jsonkit.m does not support ARC.
  22. Add jsonkit.h as a public header file in the Xcode cordovalib project’s “build phase”/”copy header”/”public file” section, so it can be found by the HWC project.
  23. Delete cordova.plist from hwc project, and add config.xml created for the Hello project into the HWC project.
    Beginning with Cordova 2.3.0, config.xml replaces cordova.plist.
  24. Delete www and capture.bundle in the HWC project to avoid build errors. Replace the file VERSION with the one created by the new Hello project.
  25. Edit the config.xml file in the HWC project to enable httpproxy and applog plugin by adding these lines:
    <feature name="AppLog">
       <param name="ios-package" value="AppLogPlugin"/>    
    </feature>    
    <feature name="HttpsProxy">        
       <param name="ios-package" value="HttpsProxyPlugin"/>
    </feature>                  
  26. Replace this code in the HWCAppDelegate.m file in the HWC project:
    #ifdef USE_CORDOVA   
    #import <Cordova/CDVViewController.h>   
    #import <Cordova/CDVContacts.h>   
    #else   
    #import "CDVViewController.h"   
    #import "CDVContacts.h"   
    #endif   
    #endif    
              
    with:
    #import <Cordova/CDVViewController.h>   
    #import <Cordova/CDVContacts.h>
  27. Add the AssetsLibrary and imageIO frameworks to the “build phase”/ “Link Binary With Libraries” section in the HWC project to avoid link errors.
  28. Delete this line from the initializeAppAfterKeyVaultUnlocked function in the HWCAppDelegate.m file:
    [CDVContacts setContactsAccessDelegate:self]; 
  29. Delete thes lines from the HWCAppDelegate.m file:
    static BOOL s_bContactsChallengeInProgress = NO;
    
    + (BOOL) isContactsChallengeInProgress
    {
       return s_bContactsChallengeInProgress;
    }
    
    - (void) requestContactsAccess {
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
       NSArray* versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
       NSInteger iMajorVersion = [[versionCompatibility objectAtIndex:0] intValue];
       if (iMajorVersion >= 6)
       {
          if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
          {
             s_bContactsChallengeInProgress = YES;
             
             ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
             ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error)
                                                      {
                                                         s_bContactsChallengeInProgress = NO;
                                                      });
             CFRelease(addressBookRef);
          }
          
          while (s_bContactsChallengeInProgress)
          {
             NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
             [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
             [pool release];
          }
       }
    #endif
    }
    
  30. Delete this line in the applicaitonWillResignActive method from the HWCAppDelete.m file:
    bPresentingContactsChallenge = [HWCAppDelegate isContactsChallengeInProgress]; 
  31. Delete this line from the HWCAppDelegate.h file:
    - (void) requestContactsAccess;
  32. Delete the protocol “MissingFeaturesProvider” from the CDVViewController interface definition from the HWCAppDeleage.h file to avoid build errors.
  33. Update cordova.js to the one provided with the new cordova library if cordova.js is used in your HybridApp.js app.