Using iOS Native Views in PhoneGap Projects

I am working on an iOS application where I want to use PhoneGap as well as a native iOS View. I want iOS view to be the first page from which user can navigate to a view created by PhoneGap. I have developed iOS applications either completely using PhoneGap or native APIs, but never tried to use both in the same application. So figuring out how to do that took some time and I thought I would share that here.

By the way, if you want to embed PhoneGap WebView into existing iOS project then follow instructions at Embedding WebViews. In this post I am going to explain how to embed native iOS view into a PhoneGap project and set it as the initial page.

First you create a PhoneGap project. I created the project using Command Line Interface of PhoneGap 3.1. Go to the folder where you want to create the project and run following command (I am assuming project name to be iOSPhoneGapProject here)

$ phonegap create iOSPhoneGapProject ram.kulkarni.iOSPhoneGapProject iOSPhoneGapApp

The first argument after create is name of the folder you want to create for your project. The next argument is the project identifier and the last one is application’s display text.

Then go into the project folder (in this case iOSPhoneGapProject) and run following command –

$ phonegap build ios

This will create iOS specific project files. Next, you add necessary plugins to get access to PhoneGap device APIs like contacts, camera etc. For example, to add contact plugin, execute following command –

$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git

You can see commands for adding more plugins in the ‘Add Plugin Features’ section of Command Line Interface. This completes the process of creating PhoneGap project from the command line.

Open the project you just created in Xcode. You will find the project file (.xcodeproj) under project folder in platforms/ios folder. You may want to run the application before making any changes to it. So run the application in simulator and make sure you see the page with ‘PhoneGap Device Is Ready’ text.

We will add a native iOS view as the first page in the application (currently it is the PhoneGap view) and add a button to it. When you click the button, it should open the PhoneGap view.

storyboard_wizardFirst we will add a Storyboard for the application. Open menu File->New->File. In the wizard, select ‘User Interface’ under iOS and then select ‘Storyboard’ icon in the right pane.

Click Next. Leave ‘Device Family’ selection to ‘iPhone’. Save the storyboard as main.storyboard in your project (or if you want to create a group and save the storyboard in that group). Click main.storyboard in the ‘Project Navigator’ view. This will open the empty storyboard.

object_libraryWe will now add a view to the storyboard. Make sure Object Library view is open in the bottom right corner of Xcode. You can also open the Object Library from menu View->Utilities->Show Object Library. Drag ‘View Controller’ from the object library and drop it on the storyboard. This will create a view in the storyboard.

 

Drag ‘Button’ from the object library and drop it on the view. Double click on the button and change the text to ‘Go To PhoneGap View’. At this point if you build the application, you might get error ‘Illegal Configuration. Auto Layout on iOS Version prior to 6.0’. The reason is that PhoneGap command-line has created the project with iOS 5 as target and auto layout is not supported in it. You can verify iOS target for the project by clicking on project name in the Project Navigator. This opens project properties. Click on General tab. In the ‘Deployment Info’ section you would see that ‘Deployment Target’ is set to ‘5.0’.

autolayout_optionIf you want to target you app for iOS 6.0 or above, you can change the value in ‘Deployment Target’ to ‘6.0’. After this change, if you build the project, then the error that you saw above will go away. But if you want to target the app for 5.0 and above, then you will have to turn off auto layout for the view controller. To do this, select ‘View Controller’ node (this node is under ‘View Controller Scene’ node) from outline in the storyboard and then click on the first icon in the top right view to show the ‘File Inspector’. You can also open the view from menu View->Utilities->Show File Inspector. In the ‘Interface Builder Document’ section, turn off ‘Use Autolayout’ option. You may also want to set ‘View as’ option to ‘iOS 6.1 and Earlier’ if you are targeting iOS 5.0. You may have to resize the button after you turn off auto layout option.

At this point if you run the application, you will not see the view that we just added. You will see the PhoneGap view that was created by the PG command line interface. This is because we haven’t told Xcode what is our main view.main_interface_xcodeYou can do so by going to project properties (click on the project name in the Project Navigator) and click on General tab. In the ‘Deployment Info’ section (the same section where we saw Deployment Target set to 5.0, as explained above), select ‘main.storyboard’ from the drop down list for ‘Main Interface’ field.

However this is not sufficient for our view to be the main interface. You can verify it by running the application, and you will see the same PhoneGap view. The reason is that when PhoneGap command line interface created the project, it created AppDelegate class (this class implements framework protocol UIApplicationDelegate and is informed about important events when application is executed) and set it up to display the view created by PhoneGap (through MainViewController class). This overrides Main Interface property that we set for the project. So, open AppDelegate.m (you will find it in Classes folder in the Project Navigator) and go to application:didFinishLaunchingWithOptions function. Comment/delete everything in this function, except the last return statement (return YES;).

If you run the application now, you will see the view we just created. If you click on ‘Go to PhoneGap View’ button, nothing happens. We now have to link PhoneGap view to this button.

In iOS, you have to define segue to create transition from one view to another – in our case from home (iOS) view to the PhoneGap view. But before we create segue, we have to embed the first view in a navigation controller.

Select View Controller from outline in the storyboard. Then select menu Editor->Embed In->Navigation Controller. This will add a navigation controller in the storyboard and link it to the first view. We will now add another View Controller and associate it with the MainViewController of PhoneGap view. So drag View Controller from Object Library to the storyboard.

Currently the class associated with the newly added View Controller is the default UIViewController. but we want to associate PhoneGap view with the MainViewController that PG command line interface had created. Select ‘View Controller’ of PG view from the outline in the storyboard. Then open ‘Identity Inspector View’. You will see that in ‘Custom Class’ section, the class associated with the View controller is UIViewController. Change the class associated with this View Controller (from UIViewController) to MainViewController

main_view_controller

We will now create a segue between the button on the first view to the PhoneGap view. To do this, hold control button and mouse button down and drag and drop on the Main View Controller. Select ‘push’ from Action Segue view.

Navigation Controller that we added, creates a navigation bar at the top of the application. We want to display view name for each in this navigation bar. Select ‘Navigation Item’ from the outline in the storyboard for the first View controller. Open ‘Attributes Inspector’ using tool bar shortcut or menu View->Utilities->Show Attributes Inspector. In the title field type ‘Home’. Then select ‘Navigation Item’ for the PhoneGap view controller and set title to ‘PhoneGap View’.

action_segue

Run the application now. The first page of the application should look like this –

ios_app_screen_1

Click the button and it should take you to the PhoneGap view.

ios_app_screen_2

Click Home link and it should take you back to the first page.

-Ram Kulkarni.

14 Replies to “Using iOS Native Views in PhoneGap Projects”

  1. Sir please give me idea about this blog when i click the go to phone gap view button then slide the view bt not display the phone gap view it display only blank screen.

    1. It is difficult to tell what could be wrong, but I would suspect MainViewController class is not associated withe the view controller for PG view. Open main.storyboard. Click on the view controller that you added for PG view. In the Identity Inspector (there is a icon at top right with tool tip ‘Show the identity inspector’), make sure Custom Class is MainViewController.

  2. Hi Ram,
    Thanks for this nice post.when i follow your post i m getting everything fine but as final when i click on “Phonegapview Button” it is showing another empty vie controller with back button.I dont know where i m struggling.your help will be appericate one

  3. – (void)webViewDidFinishLoad:(UIWebView*)theWebView
    {
    NSLog(@”web view loaded”);
    // Black base color for background matches the native apps
    theWebView.backgroundColor = [UIColor blackColor];

    return [super webViewDidFinishLoad:theWebView];
    }

    Hi Ram,
    This is Mahe Thiru.The problem when i click the phonegap button it is loading MainViewController. but it is not calling the above function,I think that s the problem

  4. Do you know of any way to put a link within the HTML to navigate to the native iOS screen, vs. needing the header on top?

    1. This is exactly what I’m trying to do…
      I tried to intercept urls from the webview and override NSURLProtocol, or create a cordova plugin, but I haven’t figured it all out yet… If you found a way, I’d love to know how !

  5. When navigating back to the PhoneGap WebView, is there a way to preserve page history if our WebView is using a SPA framework? From the example it looks like the WebView is re-created and device ready fires again.

Leave a Reply