0

I am using the following code,

var iphoneUrl = 'myScheme://{0}?{1}'
function callNativeFunction(functionName) {
    var args = Array.prototype.slice.call(arguments, 1);
    if (window.andriod) {
        andriod[functionName].apply(this, args);
    }
    else {
        var params = '';
        for (var i = 0, len = args.length; i < len; i++) {
            params += 'param' + (i + 1) + '=' + encodeURIComponent(args[i]) + '&';
        }
        params = params.slice(0, -1);// remove last &
        window.location = iphoneUrl.format(functionName, params);
    }
}
callNativeFunction('functionName', 'param1');

Here is String.Format,

String.prototype.format = function () {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function (match, number) {
        return typeof args[number] != 'undefined'
          ? args[number]
          : match
        ;
    });
};

which great but on andriod webview apply is not working. alert(andriod[functionName]) give me 'function myFunc(..){[native Code]}'. But andriod[functionName] does not call the function. Not If use andriod.myFunc then it works but I don't want the function to be hard coded.

Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322

2 Answers2

3

You’re passing this along as first argument to apply, but since the value of this is dependent on the way you call the function, it will merely reflect the global object, whereas it should reflect the andriod (sic) object.

Just replacing this in the following line by andriod should work:

andriod[functionName].apply(this, args);

into

andriod[functionName].apply(andriod, args);

Correcting andriod into android gives the following function:

var iphoneUrl = 'myScheme://{0}?{1}'
function callNativeFunction(functionName) {
    var args = Array.prototype.slice.call(arguments, 1);
    if ('android' in window) {
        window.android[functionName].apply(window.android, args);
    }
    else {
        var params = '';
        for (var i = 0, len = args.length; i < len; i++) {
            params += 'param' + (i + 1) + '=' + encodeURIComponent(args[i]) + '&';
        }
        params = params.slice(0, -1);// remove last &
        window.location = iphoneUrl.format(functionName, params);
    }
}
callNativeFunction('functionName', 'param1');
Community
  • 1
  • 1
Martijn
  • 13,225
  • 3
  • 48
  • 58
0

I have found this as a work around, Not good but works,

function apply(obj, methodName, args) {
    switch (args.length) {
        case 0: return obj[methodName]();
        case 1: return obj[methodName](args[0]);
        case 2: return obj[methodName](args[0], args[1]);
        case 3: return obj[methodName](args[0], args[1], args[2]);
        case 4: return obj[methodName](args[0], args[1], args[2], args[3]);
        case 5: return obj[methodName](args[0], args[1], args[2], args[3], args[4]);
        case 6: return obj[methodName](args[0], args[1], args[2], args[3], args[4], args[5]);
        case 7: return obj[methodName](args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
    }
}


function callNativeFunction(functionName) {
    var args = Array.prototype.slice.call(arguments, 1);
    if (window.android) {
        apply(android, functionName, args);
    }
    else {
        var params = '';
        for (var i = 0, len = args.length; i < len; i++) {
            params += 'param' + (i + 1) + '=' + encodeURIComponent(args[i]) + '&';
        }
        params = params.slice(0, -1);// remove last &
        window.location = iphoneUrl.format(functionName, params);
    }
}
Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322