Search code examples
javascriptiosobjective-ccordovaphonegap

Cordova 4.4.0 call iOS Objective-C native method not working


Update: Now the JavaScript is able to call my Objective C plugin code after event "deviceReady". BUT It only works when I push the app to the background, otherwise, it just hang there and never call my plugin code. I can see the console says when the plugin is called

[29277:15212897] THREAD WARNING: ['HybridBridge'] took '9252.614014' ms. Plugin should use a background thread.

I understand the warning "'9252.614014' ms" is caused by my manual action that push the app to the background

But WHY??? Why my Objective C plugin code is only called when the app goes to the background?


I am creating a Cordova 4.4.0 plugin for my objective C based iOS app The JavaScript is trigged successfully, however, javascript code:

cordova.exec(saySuccess, sayFailure, PLUGIN_NAME, METHOD_NAME, [page]);

It just won't trigger my Objective C code

Objective C method is not called at all

The plugin has been registered in config.xml as the following

    <feature name="HybridBridge">
        <param name="ios-package" value="HybridBridge"/>
        <param name="onload" value="true" />
    </feature>

At the following is my code, please help.

JavaScript code that calls Objective C method:

var hybridBridge = (function() {

    var PLUGIN_NAME = "HybridBridge";
    var METHOD_NAME = "loadExternalPage";

    this.loadExternalPage = function (page) {
        cordova.exec(saySuccess, sayFailure, PLUGIN_NAME, METHOD_NAME, [page]);
    };
    return this;
}());
function saySuccess() {
    alert("Success");
}

function sayFailure () {
    alert ("Failure");
}

Config.xml file:

<widget>
    <!-- Whitelist docs: https://github.com/apache/cordova-plugin-whitelist -->
    <access origin="*" />
    <!-- Grant certain URLs the ability to launch external applications. This
         behaviour is set to match that of Cordova versions before 3.6.0, and
         should be reviewed before launching an application in production. It
         may be changed in the future. -->
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <allow-intent href="itms:*" />
    <allow-intent href="itms-apps:*" />

    <!-- Preferences for iOS -->
    <preference name="AllowInlineMediaPlayback" value="false" />
    <preference name="BackupWebStorage" value="cloud" />
    <preference name="DisallowOverscroll" value="false" />
    <preference name="EnableViewportScale" value="false" />
    <preference name="KeyboardDisplayRequiresUserAction" value="true" />
    <preference name="MediaPlaybackRequiresUserAction" value="false" />
    <preference name="SuppressesIncrementalRendering" value="false" />
    <preference name="SuppressesLongPressGesture" value="false" />
    <preference name="Suppresses3DTouchGesture" value="false" />
    <preference name="GapBetweenPages" value="0" />
    <preference name="PageLength" value="0" />
    <preference name="PaginationBreakingMode" value="page" /> <!-- page, column -->
    <preference name="PaginationMode" value="unpaginated" /> <!-- unpaginated, leftToRight, topToBottom, bottomToTop, rightToLeft -->

    <feature name="LocalStorage">
        <param name="ios-package" value="CDVLocalStorage"/>
    </feature>
    <feature name="HandleOpenUrl">
        <param name="ios-package" value="CDVHandleOpenURL"/>
        <param name="onload" value="true"/>
    </feature>
    <feature name="IntentAndNavigationFilter">
        <param name="ios-package" value="CDVIntentAndNavigationFilter"/>
        <param name="onload" value="true"/>
    </feature>
    <feature name="GestureHandler">
        <param name="ios-package" value="CDVGestureHandler"/>
        <param name="onload" value="true"/>
    </feature>
    <feature name="HybridBridge">
        <param name="ios-package" value="HybridBridge"/>
        <param name="onload" value="true" />
    </feature>
</widget>

Objective C code for plugin

#import "HybridBridge.h"

@implementation HybridBridge

-(void) loadExternalPage:(CDVInvokedUrlCommand*) command {
    NSLog(@"init");
    NSString *page = [command.arguments objectAtIndex:0];
    NSString *webPage =[NSString stringWithFormat:@"%@%@", [CommonUtil readInfoPlist:@"host"], page];
    CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:webPage];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end

I really don't know why my plugin method "loadExternalPage" is not called in Objective-C. Please help.


Solution

  • OK the problem is finally resolved. It took me over 20 hours to resolve the issue, I worked to 4am and finally here is the solution: 1. Upgrade Cordova to the latest version. The current one I am using and works is Cordova 7 To install the latest Cordova:

    $ sudo npm install -g cordova
    
    1. Update the index.html to have the following

      https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

    The final words:

    It is easier to just create the project from scratch and then move things over instead of trying to upgrading the existing project, at least for me.

    And I modify the js and html files that are located under Staging/www folder in Xcode.

    Hope it helps.