Giter Site home page Giter Site logo

marcuswestin / webviewjavascriptbridge Goto Github PK

View Code? Open in Web Editor NEW
14.3K 514.0 3.0K 522 KB

An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews

Home Page: http://marcuswest.in

License: MIT License

Objective-C 73.83% HTML 6.18% Ruby 1.95% Makefile 1.52% Swift 15.40% C 0.54% Rich Text Format 0.58%

webviewjavascriptbridge's Introduction

WebViewJavascriptBridge

Circle CI

An iOS/OSX bridge for sending messages between Obj-C and JavaScript in WKWebViews, UIWebViews & WebViews.

Migration Guide

When upgrading from v5.0.x to 6.0.x you will have to update the setupWebViewJavascriptBridge javascript snippet. See https://github.com/marcuswestin/WebViewJavascriptBridge#usage part 4).

Who uses WebViewJavascriptBridge?

WebViewJavascriptBridge is used by a range of companies and projects. This is a small and incomplete sample list:

Installation (iOS & OSX)

Installation with CocoaPods

Add this to your podfile and run pod install to install:

pod 'WebViewJavascriptBridge', '~> 6.0'

Manual installation

Drag the WebViewJavascriptBridge folder into your project.

In the dialog that appears, uncheck "Copy items into destination group's folder" and select "Create groups for any folders".

Examples

See the Example Apps/ folder. Open either the iOS or OSX project and hit run to see it in action.

To use a WebViewJavascriptBridge in your own project:

Usage

  1. Import the header file and declare an ivar property:
#import "WebViewJavascriptBridge.h"

...

@property WebViewJavascriptBridge* bridge;
  1. Instantiate WebViewJavascriptBridge with a WKWebView, UIWebView (iOS) or WebView (OSX):
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
  1. Register a handler in ObjC, and call a JS handler:
[self.bridge registerHandler:@"ObjC Echo" handler:^(id data, WVJBResponseCallback responseCallback) {
	NSLog(@"ObjC Echo called with: %@", data);
	responseCallback(data);
}];
[self.bridge callHandler:@"JS Echo" data:nil responseCallback:^(id responseData) {
	NSLog(@"ObjC received response: %@", responseData);
}];
  1. Copy and paste setupWebViewJavascriptBridge into your JS:
function setupWebViewJavascriptBridge(callback) {
	if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
	if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
	window.WVJBCallbacks = [callback];
	var WVJBIframe = document.createElement('iframe');
	WVJBIframe.style.display = 'none';
	WVJBIframe.src = 'https://__bridge_loaded__';
	document.documentElement.appendChild(WVJBIframe);
	setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
  1. Finally, call setupWebViewJavascriptBridge and then use the bridge to register handlers and call ObjC handlers:
setupWebViewJavascriptBridge(function(bridge) {
	
	/* Initialize your app here */

	bridge.registerHandler('JS Echo', function(data, responseCallback) {
		console.log("JS Echo called with:", data)
		responseCallback(data)
	})
	bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) {
		console.log("JS received response:", responseData)
	})
})

Automatic reference counting (ARC)

This library relies on ARC, so if you use ARC in you project, all works fine. But if your project have no ARC support, be sure to do next steps:

  1. In your Xcode project open project settings -> 'Build Phases'

  2. Expand 'Compile Sources' header and find all *.m files which are belongs to this library. Make attention on the 'Compiler Flags' in front of each source file in this list

  3. For each file add '-fobjc-arc' flag

Now all WVJB files will be compiled with ARC support.

Contributors & Forks

Contributors: https://github.com/marcuswestin/WebViewJavascriptBridge/graphs/contributors

Forks: https://github.com/marcuswestin/WebViewJavascriptBridge/network/members

API Reference

ObjC API

[WebViewJavascriptBridge bridgeForWebView:(WKWebVIew/UIWebView/WebView*)webview

Create a javascript bridge for the given web view.

Example:

[WebViewJavascriptBridge bridgeForWebView:webView];
[bridge registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler]

Register a handler called handlerName. The javascript can then call this handler with WebViewJavascriptBridge.callHandler("handlerName").

Example:

[self.bridge registerHandler:@"getScreenHeight" handler:^(id data, WVJBResponseCallback responseCallback) {
	responseCallback([NSNumber numberWithInt:[UIScreen mainScreen].bounds.size.height]);
}];
[self.bridge registerHandler:@"log" handler:^(id data, WVJBResponseCallback responseCallback) {
	NSLog(@"Log: %@", data);
}];
[bridge callHandler:(NSString*)handlerName data:(id)data]
[bridge callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)callback]

Call the javascript handler called handlerName. If a responseCallback block is given the javascript handler can respond.

Example:

[self.bridge callHandler:@"showAlert" data:@"Hi from ObjC to JS!"];
[self.bridge callHandler:@"getCurrentPageUrl" data:nil responseCallback:^(id responseData) {
	NSLog(@"Current UIWebView page URL is: %@", responseData);
}];

[bridge setWebViewDelegate:(id)webViewDelegate]

Optionally, set a WKNavigationDelegate/UIWebViewDelegate if you need to respond to the web view's lifecycle events.

[bridge disableJavscriptAlertBoxSafetyTimeout]

UNSAFE. Speed up bridge message passing by disabling the setTimeout safety check. It is only safe to disable this safety check if you do not call any of the javascript popup box functions (alert, confirm, and prompt). If you call any of these functions from the bridged javascript code, the app will hang.

Example:

[self.bridge disableJavscriptAlertBoxSafetyTimeout];

Javascript API

bridge.registerHandler("handlerName", function(responseData) { ... })

Register a handler called handlerName. The ObjC can then call this handler with [bridge callHandler:"handlerName" data:@"Foo"] and [bridge callHandler:"handlerName" data:@"Foo" responseCallback:^(id responseData) { ... }]

Example:

bridge.registerHandler("showAlert", function(data) { alert(data) })
bridge.registerHandler("getCurrentPageUrl", function(data, responseCallback) {
	responseCallback(document.location.toString())
})
bridge.callHandler("handlerName", data)
bridge.callHandler("handlerName", data, function responseCallback(responseData) { ... })

Call an ObjC handler called handlerName. If a responseCallback function is given the ObjC handler can respond.

Example:

bridge.callHandler("Log", "Foo")
bridge.callHandler("getScreenHeight", null, function(response) {
	alert('Screen height:' + response)
})
bridge.disableJavscriptAlertBoxSafetyTimeout()

Calling bridge.disableJavscriptAlertBoxSafetyTimeout() has the same effect as calling [bridge disableJavscriptAlertBoxSafetyTimeout]; in ObjC.

Example:

bridge.disableJavscriptAlertBoxSafetyTimeout()

webviewjavascriptbridge's People

Contributors

bastibense avatar chrisvariety avatar coderyi avatar cutmail avatar ddovod avatar ejameslin avatar gotomanners avatar javache avatar jberkman avatar lbj96347 avatar lokimeyburg avatar marcuswestin avatar mbishop-fiksu avatar milesmatthias avatar nolanw avatar oakho avatar originme avatar pj4533 avatar psineur avatar pushpak avatar ruslanskorb avatar sergiocampama avatar stringbean avatar tanis2000 avatar vontio avatar wenluma avatar xiaojianxiaoxu avatar yas375 avatar yiplee avatar yukimunet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webviewjavascriptbridge's Issues

Bridge prevents phonegap from loading app

I'm trying to add a WebViewJavascriptBridge to my existing phonegap application, but when I try to add the bridge to the webview, my application never loads past the splash screen.

I have this in didFinishLaunchingWithOptions:

WebViewJavascriptBridge* javascriptBridge = [WebViewJavascriptBridge javascriptBridgeForWebView:self.viewController.webView handler:^(id data, WVJBResponseCallback callback) {
    NSLog(@"Received message from javascript: %@", data);
}];

I see that the events get fired, but my app doesn't load. Is this is an issue, or is there something I'm missing that's breaking startup?

Porting to WKWebView

It was good to work with WVJsBrige as a component for fluid interop between native and web code. I'd love to continue using WKWebView as I port the reference WebView-based app framework for our products and client projects.

Until 10.10 becomes stable enough to develop in, we can use the iOS 8 SDK to start working on a port. I'd like to start one soon, and would love to hear from you regarding how you'd plan out an attack. Any feedback or advice would be welcome here.

SSL

It doesn't work with https

ViewController does not dealloc when push to another view

I have dealloc problem when using WVJB enable UIWebView. I think problem maybe the memory management. Right?

Without WVJB
A -> push -> B (UIWevView) -> pop back -> A (A trigger dealloc) -> B (UIWebView)

With WVJB
A -> push -> B (UIWevView) -> pop back -> A (A not trigger dealloc) -> B (UIWevView but nothing happen here)

Without WVJB

_webView = [viewController webView];
[_webView setDelegate:self];

With WVJB

 _webView = [viewController webView];
[WebViewJavascriptBridge enableLogging];
_bridge = [WebViewJavascriptBridge bridgeForWebView:_webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"ObjC received message from JS: %@", data);
    responseCallback(@"Response for message from ObjC");
}];

Exception when calling "callHandler" without data

It seems that the following leads to an exception when data == nil.

- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName {
    NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"];

The problem is that a dictionary can not contain "nil" as a value for a key.

How about registering to Bower repository?

Hi,

I'm developing an iOS app which communicates with UIWebView. And thank you for your great library.

I'm managing all the components loaded in a WebView side with Bower.
WebViewJavascriptBridge has a text file which is injected into a webView and executed as JavaScript.

I wanted to manage the script with bower as well as other libraries, and searched for it.
There is a hit in the bower repository named WebViewJSBridge.js managed by a third party, and seems to be just a copy of your script.
https://github.com/quangpham/WebViewJsBridge

The bower entry has nothing to do with your WebViewJavascriptBridge, and may not guaranteed to be updated.
Why don't you create a bower entry yourself?

Sample app crashed on iOS 5+

Example project crashes on iOS5+

CALLBACK_ARGUMENTS_KEY
in webviewJavascriptBridge

  • (void)webViewDidFinishLoad:(UIWebView *)webView

webViewDidFinishLoad would be called after all element loaded

I found that brigde code inject into the html , after webViewDidFinishLoad, as I know, this event would be called after all element load. We may wait for a minute if one image request time out.
And I want to received a message when the html did load ,and show. Not wait for image show.
How can I do?

not working for ios 7 iphone 5s 64 bit or ipad 64bit

the bridge stops working in above environment.
I step into code, and found that in WebViewJavascriptBridge.m
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"];

filePath is nil in above environment, working in other environment.

found a stackover flow thread about the nsbundle loading issue:
http://stackoverflow.com/questions/18888212/after-ios-7-update-pathforresource-returns-nil

is it possible to release a fix for that?

thanks.

Periodic crashes in jsCode in _sendMessage.

Hi!

There' a lot of a little bit dirty commits in history, so i'm unable to provide a pull request right now.
However, i want to inform all WebViewJavascriptBridge users, that there's a bug, that may lead to losing some messages from JS.

We've fixed that bug and isolated fix's diff in one commit.
Here it is: psineur@a6c39ff

Also in my develop branch i added customization to Bridge's JS Object & Method names, so probably you would like to take a look.

Cheers!

WVJB doesn't work with JavaScript loaded with windowScriptObject?

This isn't a huge deal, but I just wanted to confirm whether anyone has experienced this issue. I'm trying to load dynamically-created HTML in my webView:

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"about:blank"]];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

[self.mainFrame loadRequest:request];
[self setEditable:YES];
[self setNeedsDisplay:YES];

NSBundle *webTechBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle]   
                                    pathForResource:@"MyWebTechBundle"
                                    ofType:@"bundle"]];

NSMutableArray *scripts = @[@"js1.js", @"js2.js", @"js3.js"].mutableCopy;
for (NSString *script in scripts.copy) {
    NSString *filePath  = [webTechBundle pathForResource:[script stringByDeletingPathExtension] ofType:script.pathExtension];
    NSString *fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    [scripts replaceObjectAtIndex:[scripts indexOfObject:script] withObject:fileContents];
}

[self.windowScriptObject evaluateWebScript:[scripts componentsJoinedByString:@";"]];

self.webViewbridge = [WebViewJavascriptBridge bridgeForWebView:self handler:^(id data, WVJBResponseCallback responseCallback) {

            NSLog(@"from DOM: %@", data);

}];

Whatever I do to dynamically load scripts, WBJB never works. It only seems to work with pre-defined html files. Has any testing been done with windowScriptObject?

Integrating to C++ project

Hello,
First, I would like to say that I'm new to objective-C world so I'm sorry if my question is too lame...

I'm currently trying to integrate this bridge into my C++ project and I have some issues targeting an iOS device.

What I've done is simple, I've just put the WebViewJavascriptBridge.* files to my project and compiled it with -x and objective-c++ flags.

On WebViewJavascriptBridge.h, I have a lot of semantic issue with WVJB_WEBVIEW_TYPE but after a quick search I found that adding the import of UIKit is enough to remove these errors.

But know, I have 12 semantic issues into WebViewJavascriptBridge.m with typeof and strongDelegate and I don't know how to fix that.

Do you have any idea of what can be the origin of these issues ? Did I do something wrong ?

Thanks in advance for your answer.

how to replace the block with delegate? I can't use 'self' in block.

if I use self, it occur problem. how to visit "self" in block? or may I replace the block with a delegate?thanks,
any demo or example?

[_jsb registerHandler:@"mead_action" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"mead_action called: %@", data);
CommonWebViewController* wvc = [[CommonWebViewController alloc]init];
wvc.path = [data objectForKey:@"path"];
wvc.fileName = [data objectForKey:@"fileName"];
wvc.arg = [data objectForKey:@"arg"];
wvc.navigationItem.title = [data objectForKey:@"viewTitle"];
//if I use self, it occur problem. how to visit "self" in block? or may I replace the block with a delegate?thanks,
[self.navigationController pushViewController:wvc animated:YES];
responseCallback(@"Response:OK");
}];

serious bug for WebViewJavascriptBridge

After load a url,the webViewDidFinishLoad called twice each time! And the webview.isLoading always is YES. In my opinion,It's error,because the page have been loaded, why it is still isLoading? can anyone explain it?

Return values for native functions called from JS

First of all, thanks for this great library! It works great :)

I was wondering if you've got any idea about how to implement returning values to JS from native calls. I've not been able to come up with a good solution so far, but it'd be awesome to be able to calla a native Obj-C function and get a return value back.

Podspec is incorrect

There is a problem in the podspec:

  s.resource     = 'WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt'

"WebViewJavascriptBridgeAbstract/..." is referenced, although it should be "WebViewJavascriptBridge/...".

This results in the JavaScript file not being included in the project and JavaScript exceptions. I think someone fixed that for the Podspec in the official repository, since that works just fine (but it's outdated).

returning object from obj c to js on button click

Hi marcus,

i want the handler to be called only when the getNameListBttnTapped method is triggered following is the script

<script> var bridge function getNameListBttnTapped(){ alert('inside getNameListBttnTapped') bridge.callHandler('testObjcCallback', {'foo': 'bar'}, function(response) { log('JS got response', response) alert(response) }) } window.onerror = function(err) { log('window.onerror: ' + err) } document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false) function onBridgeReady(event) { bridge = event.bridge } </script>

Here is the code, i have used for registering the handler.

[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"testObjcCallback called: %@", data);
responseCallback(@"Response from testObjcCallback");
}];

when i tap on the GetNameList button handler is called and the response is sent to webview javascript bridge, but the function(response) is not triggered.Please help me to solve the issue.

Can this be used with a UIViewController?

Hi,

I'm trying to build a Hybrid app using the bridge (I'm literally a few days old in iOS dev) .

have a tabbar navigation based app, and I'm using a UIViewController for each tab view, one of the tab would use the WebView.
I wast sure if I could implement WebViewJavascriptBridgeDelegate in a UIViewController class like below.

@interface CurrentTimeViewController : UIViewController <UIWebViewDelegate, WebViewJavascriptBridgeDelegate>

I get a EXC_BAD_ACC during runtime in the main class

int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Any pointer would be much appreciated.
-Imran

Performance issues

Hello,
I'm still working on an iOS project using UIWebView, and I need to use this WebViewJavascriptBridge to propagate JS events like touches events.

Until now, I didn't used the bridge, I had a event listener JS side that put each event content into an array and C++ side I just called the Objective-C function named stringByEvaluatingJavaScriptFromString of my UIWebView to access to this event content.

The problem is that I always have to check if an event has been added to my array whereas it would be much more better to use the bridge JS side to directly raise the event C++ side.

That's what I tried to do but that doesn't work very well.

First, if I take the example of touches events, when I move my fingers, there is a lot of events that are triggered very quickly and the bridge stop to transmite messages after a little moment until I release my fingers out of the surface after what the bridge send all messages that it couldn't send before.

Second, I've test a little project with a single rotating cube and a webview over it to catch events. When I move a finger over the surface, the events are sent but the cube freezes during that. I don't have this issue using my former method without the bridge.

Do you know how can I resolve these problems ?

Thank you very much in advance.

iOS 7 support?

Has this been tested in iOS 7 and XCode 5? I've been using it the last couple of days and am not seeing any sent messages from Obj C to JS. JS calling Obj C works, but not vice versa.

Detecting iOS Deployment Target at compile time

The following codes in WebViewJavascriptBridgeAbstract.h would not work when my project's deployment target was set to iOS 4.3


if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0)

#define WEAK_FALLBACK weak

elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7)

#define WEAK_FALLBACK weak

else

#define WEAK_FALLBACK unsafe_unretained

endif


I think following changes can reach same propose and might be more straightforward

if __has_feature(objc_arc_weak)

#define WEAK_FALLBACK weak

else

#define WEAK_FALLBACK unsafe_unretained

endif


'webViewDidFinishLoad' did not call when use "webViewDelegate:self" as documented

There is not error any more. Webview load url completely but not trigger call webViewDidFinishLoad

System: IOS7, iPhone4s

DetailViewController.h

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController<UIWebViewDelegate>

@property (strong, nonatomic) id detailId;
@property (strong, nonatomic) id detailTitle;

@property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;

@end

DetailViewController.m

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSLog(@"Hide loading animation");
    [MBProgressHUD hideHUDForView:self.view animated:YES];
}

- (void)viewDidLoad
{
    UIWebView *webView = [viewController webView];
    [[webView scrollView] setBounces:NO];  
    [WebViewJavascriptBridge enableLogging];
    WebViewJavascriptBridge* bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"Received message from javascript: %@", data);
        if (responseCallback) {
            responseCallback(@"Right back atcha");
        }
    }];
}

timing of page load and WebViewJavascriptBridgeReady event

I've experienced problems connecting the page with the bridge in a couple of different instances, and in both cases it was due to the page not loading fast enough to start listening for the WebViewJavascriptBridgeReady event.

The problem may occur when you have components that use the bridge that are executed well after the page is initially loaded, for example, I was trying to connect to the bridge in an AngularJS app which has a prolonged page load sequence.

The other problem I saw was that the webViewDidFinishLoad: was being fired before all the scripts had loaded. In this case the scripts were at the bottom of the <body> element so perhaps UIWebView is considering the body of the page effectively loaded since the scripts don't contribute to the initial rendering. The result was, again, that the WebViewJavascriptBridgeReady event was being fired before the page JS could listen to it.

Anyway, long story short, the solution for me was to do something like this:

function connectToBridge(fn) {
  if (window.WebViewJavascriptBridge) {
    fn(WebViewJavascriptBridge);
  } else {
    document.addEventListener('WebViewJavascriptBridgeReady', function(ev) {
      fn(ev.bridge);
    });
  }
}

connectToBridge(function (bridge) {
  bridge.init(function (msg) {
      ...
  });
});

Essentially, detect that bridge hasn't already loaded before listening for the event.

I wondered if you'd consider putting this on the README.md? Might save somebody else some time.

Otherwise, WebViewJavascriptBridge is awesome, thank you!

Trouble getting this to work in a UIViewController

I tried this from what I read in some other issues. But there seems to be no protocol defined.

@interface MyViewController : UIViewController

So I tried:

@interface MyViewController : UIViewController

this still doesn't do anything. Following your instruction worked fine from my appdelegate. but whenever I bring it over to a viewcontroller it doesn't even log any output

I want subview loading indicator in alertView

Hi. I really thankyou for your Code.

But there is a issue for me.
I tried add UIActivtyIndicatorView in UIAlertView when web is loading.

in normal case I added addSubView code in webViewDidStartLoad and dismiss in webViewDidFinishLoad. It worked well.

But after add WebViewJavascriptBridge, i added addSubView in WebViewJavascriptBridge's webview delegate.. but the alertView popup 3times.
and it didn't dismiss
i think when ObjC comunicate with Javascrtipt webViewDidStartLoad is called.. everytimes

i tried

for (UIWindow* window in [UIApplication sharedApplication].windows) {
NSArray* subviews = window.subviews;
if ([subviews count] > 0)
if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])
[(UIAlertView *)[subviews objectAtIndex:0] dismissWithClickedButtonIndex:[(UIAlertView *)[subviews objectAtIndex:0] cancelButtonIndex] animated:NO];
}

in webViewDidFinishLoad but it didn't worked.

is there any solution?

sorry i'm really not good at English.

EXEC_BAD_ACCESS error?

Hello Marcus!

Excellent library! I'm a very new iOS developer (I only started a few days ago), and I'm trying to utilize the bridge with a UIWebView that I've got on my Storyboard. Whenever I try to use it, I get an EXEC_BAD_ACCESS error.

The trouble lines seem to be:

- (void)viewDidLoad
{
    [super viewDidLoad];

    WebViewJavascriptBridge* bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"Received message from javascript: %@", data);
        responseCallback(@"Right back atcha");
    }];

    webView.scrollView.bounces = NO;

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

    NSString *path = [[NSBundle mainBundle] bundlePath];
    path = [NSString stringWithFormat:@"%@/%s", path, "htdocs/index.html"];
    NSURL *URL = [NSURL fileURLWithPath:path];

    [webView loadRequest:[[NSURLRequest alloc] initWithURL:URL]];
}

To be exact, the last line. If I don't make that request, I don't get the error. I've tried it with a UIWebView created just in Objective-C, and still gotten the error, although maybe I did it wrong.

Any suggestions?

Secret

Hi,
first of all very good job!
So, there is a secret string property not used. Why?

Thanks
regards
GF

Pass in image from Photo album?

Hi Marcus, thanks for yours great code. I was wondering if it would be possible to trigger an UIImagePickerController from the javascript, choose a photo and give it back to the javascript? I would like to use it as a workaround for file upload which is unavailable on safari. Any guidance would be much appreciated.

Many thanks,
Leo

Why the html content be loaded twice?

I code the test program.
the .h file is

//
// ViewController.h
// test
//
// Created by remote roamer on 12-5-3.
// Copyright (c) 2012年 MyCompanyName. All rights reserved.
//

import <UIKit/UIKit.h>

import "WebViewJavascriptBridge.h"

import "AppDelegate.h"

@Class AppDelegate;

@interface ViewController : UIViewController < WebViewJavascriptBridgeDelegate >
{
IBOutlet UIWebView * webView;
}

@Property(retain,nonatomic) UIWebView * webView;

@Property(retain,nonatomic) WebViewJavascriptBridge * javascriptBridge;

@Property(nonatomic,retain) NSBundle* bundle ;

@EnD

the .m file :

//
// ViewController.m
// test
//
// Created by remote roamer on 12-5-3.
// Copyright (c) 2012年 MyCompanyName. All rights reserved.
//

import "ViewController.h"

@interface ViewController ()

@EnD

@implementation ViewController
@synthesize webView;
@synthesize bundle;
@synthesize javascriptBridge;

-(void) javascriptBridge:(WebViewJavascriptBridge *)bridge receivedMessage:(NSString *)message fromWebView:(UIWebView *)webView
{

}

-(void) webViewDidStartLoad:(UIWebView *)webView
{
NSLog(@"loading html start");
//[MBProgressHUD showHUDAddedTo:self.webView animated:YES];
}

-(void) webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"load html finish.");
//[MBProgressHUD hideHUDForView:self.webView animated:YES];
}

-(void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(@"load html error:%@",error);
//[MBProgressHUD hideHUDForView:self.webView animated:YES];
}

  • (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization
    NSLog(@"initWithNibName");
    //self.javascriptBridge = [WebViewJavascriptBridge javascriptBridgeWithDelegate: (AppDelegate *)([UIApplication sharedApplication]).delegate];
    self.javascriptBridge = [WebViewJavascriptBridge javascriptBridgeWithDelegate:self];

    }
    return self;
    }

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    NSLog(@"viewDidLoad");

    //self.webView.delegate = self;
    self.webView.delegate = self.javascriptBridge;
    self.bundle = [NSBundle mainBundle];
    [webView loadHTMLString:@"aaa" baseURL:[NSURL fileURLWithPath:[bundle bundlePath]]];

    // Do any additional setup after loading the view, typically from a nib.
    }

  • (void)viewDidUnload
    {

    [super viewDidUnload];
    // Release any retained subviews of the main view.
    }

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
    return YES;
    }

@EnD

When I run it , the logger info in console is :

2012-05-03 20:11:06.777 test[14860:f803] initWithNibName
2012-05-03 20:11:06.791 test[14860:f803] viewDidLoad
2012-05-03 20:11:06.813 test[14860:f803] loading html start
2012-05-03 20:11:06.836 test[14860:f803] loading html start
2012-05-03 20:11:06.837 test[14860:f803] load html finish.
2012-05-03 20:11:06.840 test[14860:f803] load html finish.

Why the html connent loaded twice?

ps: I‘m using the xcode 4.3.2 and the sdk is 5.1

Please add semantic version tags.

I’ve recently added WebViewJavascriptBridge to the CocoaPods package manager repo.

CocoaPods is a tool for managing dependencies for OS X and iOS Xcode projects and provides a central repository for iOS/OS X libraries. This makes adding libraries to a project and updating them extremely easy and it will help users to resolve dependencies of the libraries they use.

However, WebViewJavascriptBridge doesn't have any version tags. I’ve added the current HEAD as version 0.0.1, but a version tag will make dependency resolution much easier.

Semantic version tags (instead of plain commit hashes/revisions) allow for resolution of cross-dependencies.

In case you didn’t know this yet; you can tag the current HEAD as, for instance, version 1.0.0, like so:

$ git tag -a 1.0.0 -m "Tag release 1.0.0"
$ git push --tags

Unable to load nib file: MainMenu, exiting

The OSX example app fails to run. The console offers this message:

Unable to load nib file: MainMenu, exiting

I can't see MainMenu.xib or anything related in the Examples directory. Why is it omitted?

sendMessage sometimes does not fire _flushMessageQueueFromWebView

sendMessage was called after onBridgeReady.
I couldn't reproduce this consistently.

it seems that _readyMessageIframe.src = customProtocol://queueHasMessage was not called correctly for some reasons.

Result:
message was pushed to sendMessageQueue
webview shouldStartLoadWithRequest was called
but the URL was about:blank instead of customProtocol://queueHasMessage
and thus _flushMessageQueueFromWebView is not triggered.

If I call _flushMessageQueueFromWebView without checking the protocol, the flushing will work but there're extra unnecessary overheads.

pagehide event

I have an issue where I'd like to send a message from the page hide event. The event itself does get called however if I call WebViewJavascriptBridge.sendMessage within that the message is never received. I assume this is because the iframe doesn't reload prior to the next page being displayed so it may not be possible to get round this. Apart from restructuring so there is a wrapper page with the displayed content and an iframe in.

window.addEventListener('pagehide', function () { WebViewJavascriptBridge.sendMessage('page hide'); }, false);

For now I think I can work around it with catching the subsequent page loads.

Using WebViewJavascriptBridge in existing storyboard UIWebView

Hi,

I ran the example code for iPhone 5.1 Simulator and everything works fine.

I'm using Xcode 4.4 with the storyboard and I already have a UIWebView. I pasted this code from the example usage into the viewDidLoad event

WebViewJavascriptBridge* bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponse* response) {
NSLog(@"Received message from javascript: %@", data);
[response respondWith:@"Right back atcha"];
// or [response respondWithError:]
}];

but got this error "no known class for selector 'bridgeForWebView'

Did I do something wrong or can I not use it in the manner? Any suggestion on how to use this appropriately in my case?

Thanks for your help,
Kalvin

Problem with HTML that contains empty iframe

Hello again,

I finally successfully compile the WebViewJavascriptBridge in C++ and I can now use it, but I still have a problem.

The library works well when I tried with a simple HTML page but if I put an empty iframe, I can't send messages like before, it can't find the variable WebViewJavascriptBridge.

In fact, the file WebViewJavascriptBridge.js.txt is loaded after I try to send my message instead of without the empty iframe, this file is loaded before.

Do you know why ?

Thanks in advance.

return values for asynchronous javascript calls

Hi marcus,

i have a javascript method like this

         phoneBridge.isAvailable=function isAvailable(featurename){

               bridge.callhandler('registerIsAvailable',featurename,function(response){
                           return response;
        })
     }

Since the call to this method is asynchronous, i could not returnn the values. Javascript is not waiting untill the method is executed.Could you please suggest me a way to return the values.Please help me to solve this issue.

How to get data asynchronously and transfer to javascript

I used AFNetWorking to fetch data from remote service API, when the data ready, I tried to transfer the data back to javascript, but it raise an error. Any advice is appreciate. My code look like this.

^(id data, WVJBResponseCallback responseCallback) {
            NSLog(@"data: %@", data);
            NSString *service = [data objectForKey:@"service"];
            BOOL needLogin = [[data objectForKey:@"needLogin"] boolValue];
            NSDictionary *businessParams = [data objectForKey:@"businessParams"];

            [[AHAPIClient sharedClient] consumeRemoteService:service
                                                   needLogin:needLogin
                                              withParameters:businessParams
                                                     success:^(id JSON) {
                                                         responseCallback(JSON);
                                                     }
                                                     failure:^(NSError *error) {
                                                         responseCallback(error.userInfo);
                                                     }];
}

EXC_BAD_ACCESS in webViewDidFinishLoad

I was using 4.0.2 when this problem occured, so I upgraded to 4.1.0 to be sure. It still happens.

For some inexplicable reason I've started getting EXC_BAD_ACCESS when loading a web view that has the WVJB initialized with it.

The view controller I'm in is a basic UIViewController that is also a UIWebViewDelegate. I still need access to the webview's callbacks after WVJB has done its thing.

I initialize the bridge into the webview as follows.

    // initialize webview bridge
    [WebViewJavascriptBridge enableLogging];
    bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
        NSString *type = [data valueForKey:@"type"];
        if ([type isEqualToString:@"photo-upload"]) {
            AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
            [delegate switchToCameraUI];
        }
    }];

Here's the back trace:

* thread #1: tid = 0x26bc1d, 0x018ca0b2 libobjc.A.dylib`objc_msgSend + 14, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=2, address=0x1a)
    frame #0: 0x018ca0b2 libobjc.A.dylib`objc_msgSend + 14
    frame #1: 0x00019883 HealthyU`-[WebViewJavascriptBridge webViewDidFinishLoad:](self=0x0fc20330, _cmd=0x00bce8cb, webView=0x0fcf5c70) + 595 at WebViewJavascriptBridge.m:339
    frame #2: 0x0065cd54 UIKit`-[UIWebView webView:didFinishLoadForFrame:] + 388
    frame #3: 0x0065ec42 UIKit`-[UIWebViewWebViewDelegate webView:didFinishLoadForFrame:] + 56
    frame #4: 0x0219fd1d CoreFoundation`__invoking___ + 29
    frame #5: 0x0219fc2a CoreFoundation`-[NSInvocation invoke] + 362
    frame #6: 0x0219fdaa CoreFoundation`-[NSInvocation invokeWithTarget:] + 74
    frame #7: 0x04cc011d WebKit`-[_WebSafeForwarder forwardInvocation:] + 157
    frame #8: 0x0219b6da CoreFoundation`___forwarding___ + 458
    frame #9: 0x0219b4ee CoreFoundation`_CF_forwarding_prep_0 + 14
    frame #10: 0x0219fd1d CoreFoundation`__invoking___ + 29
    frame #11: 0x0219fc2a CoreFoundation`-[NSInvocation invoke] + 362
    frame #12: 0x05cd18a9 WebCore`SendDelegateMessage(NSInvocation*) + 201
    frame #13: 0x04c40861 WebKit`CallFrameLoadDelegate(objc_object* (*)(objc_object*, objc_selector*, ...), WebView*, objc_selector, objc_object*) + 145
    frame #14: 0x04c62dff WebKit`WebFrameLoaderClient::dispatchDidFinishLoad() + 207
    frame #15: 0x0517bffa WebCore`WebCore::FrameLoader::checkLoadCompleteForThisFrame() + 282
    frame #16: 0x051741b0 WebCore`WebCore::FrameLoader::checkLoadComplete() + 208
    frame #17: 0x05017d5d WebCore`WebCore::DocumentLoader::finishedLoading(double) + 605
    frame #18: 0x0501c0e8 WebCore`WebCore::DocumentLoader::maybeLoadEmpty() + 744
    frame #19: 0x0501c40d WebCore`WebCore::DocumentLoader::startLoadingMainResource() + 349
    frame #20: 0x0517cad7 WebCore`WebCore::FrameLoader::continueLoadAfterWillSubmitForm() + 167
    frame #21: 0x05179847 WebCore`WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) + 695
    frame #22: 0x051798e0 WebCore`WebCore::FrameLoader::callContinueLoadAfterNavigationPolicy(void*, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) + 48
    frame #23: 0x058a9f15 WebCore`WebCore::PolicyCallback::call(bool) + 69
    frame #24: 0x058aac1f WebCore`WebCore::PolicyChecker::continueAfterNavigationPolicy(WebCore::PolicyAction) + 799
    frame #25: 0x04c68a0c WebKit`-[WebFramePolicyListener receivedPolicyDecision:] + 92
    frame #26: 0x04c68af9 WebKit`-[WebFramePolicyListener use] + 41
    frame #27: 0x0065c452 UIKit`-[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 776
    frame #28: 0x0065e854 UIKit`-[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 77
    frame #29: 0x0219fd1d CoreFoundation`__invoking___ + 29
    frame #30: 0x0219fc2a CoreFoundation`-[NSInvocation invoke] + 362
    frame #31: 0x0219fdaa CoreFoundation`-[NSInvocation invokeWithTarget:] + 74
    frame #32: 0x04cc011d WebKit`-[_WebSafeForwarder forwardInvocation:] + 157
    frame #33: 0x0219b6da CoreFoundation`___forwarding___ + 458
    frame #34: 0x0219b4ee CoreFoundation`_CF_forwarding_prep_0 + 14
    frame #35: 0x04c638b1 WebKit`WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(void (WebCore::PolicyChecker::*)(WebCore::PolicyAction), WebCore::NavigationAction const&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>) + 225
    frame #36: 0x058aa73b WebCore`WebCore::PolicyChecker::checkNavigationPolicy(WebCore::ResourceRequest const&, WebCore::DocumentLoader*, WTF::PassRefPtr<WebCore::FormState>, void (*)(void*, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool), void*) + 1147
    frame #37: 0x051790ca WebCore`WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>) + 922
    frame #38: 0x0517810d WebCore`WebCore::FrameLoader::loadWithNavigationAction(WebCore::ResourceRequest const&, WebCore::NavigationAction const&, bool, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>) + 573
    frame #39: 0x05175c61 WebCore`WebCore::FrameLoader::loadURL(WebCore::KURL const&, WTF::String const&, WTF::String const&, bool, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::Event>, WTF::PassRefPtr<WebCore::FormState>) + 1297
    frame #40: 0x0517450e WebCore`WebCore::FrameLoader::loadURLIntoChildFrame(WebCore::KURL const&, WTF::String const&, WebCore::Frame*) + 366
    frame #41: 0x04c66482 WebKit`WebFrameLoaderClient::createFrame(WebCore::KURL const&, WTF::String const&, WebCore::HTMLFrameOwnerElement*, WTF::String const&, bool, int, int) + 354
    frame #42: 0x05b5c9a1 WebCore`WebCore::SubframeLoader::loadSubframe(WebCore::HTMLFrameOwnerElement*, WebCore::KURL const&, WTF::String const&, WTF::String const&) + 289
    frame #43: 0x05b5b05f WebCore`WebCore::SubframeLoader::loadOrRedirectSubframe(WebCore::HTMLFrameOwnerElement*, WebCore::KURL const&, WTF::AtomicString const&, bool, bool) + 191
    frame #44: 0x05b5ae10 WebCore`WebCore::SubframeLoader::requestFrame(WebCore::HTMLFrameOwnerElement*, WTF::String const&, WTF::AtomicString const&, bool, bool) + 672
    frame #45: 0x05234b4c WebCore`WebCore::HTMLFrameElementBase::openURL(bool, bool) + 188
    frame #46: 0x052352ca WebCore`WebCore::HTMLFrameElementBase::setNameAndOpenURL() + 410
    frame #47: 0x04ee0399 WebCore`WebCore::ChildNodeInsertionNotifier::notify(WebCore::Node*) + 249
    frame #48: 0x04edcafb WebCore`WebCore::updateTreeAfterInsertion(WebCore::ContainerNode*, WebCore::Node*, WebCore::AttachBehavior) + 155
    frame #49: 0x04edc73c WebCore`WebCore::ContainerNode::appendChild(WTF::PassRefPtr<WebCore::Node>, int&, WebCore::AttachBehavior) + 348
    frame #50: 0x0586b12d WebCore`WebCore::Node::appendChild(WTF::PassRefPtr<WebCore::Node>, int&, WebCore::AttachBehavior) + 61
    frame #51: 0x0560954b WebCore`WebCore::JSNode::appendChild(JSC::ExecState*) + 107
    frame #52: 0x05606883 WebCore`WebCore::jsNodePrototypeFunctionAppendChild(JSC::ExecState*) + 115
    frame #53: 0x72ce87cf
    frame #54: 0x0977a1ac JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 5532
    frame #55: 0x0967dcad JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*) + 525
    frame #56: 0x055d118b WebCore`WebCore::JSMainThreadExecState::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*) + 91
    frame #57: 0x05a7fdd6 WebCore`WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld*) + 262
    frame #58: 0x05a80088 WebCore`WebCore::ScriptController::evaluate(WebCore::ScriptSourceCode const&) + 40
    frame #59: 0x05a82d35 WebCore`WebCore::ScriptController::executeScript(WebCore::ScriptSourceCode const&) + 101
    frame #60: 0x05a82bc4 WebCore`WebCore::ScriptController::executeScript(WTF::String const&, bool) + 116
    frame #61: 0x04c4ea5a WebKit`-[WebFrame(WebInternal) _stringByEvaluatingJavaScriptFromString:forceUserGesture:] + 298
    frame #62: 0x04c4e920 WebKit`-[WebFrame(WebInternal) _stringByEvaluatingJavaScriptFromString:] + 48
    frame #63: 0x04cc2c1b WebKit`-[WebView stringByEvaluatingJavaScriptFromString:] + 59
    frame #64: 0x0065aa78 UIKit`-[UIWebView stringByEvaluatingJavaScriptFromString:] + 84
    frame #65: 0x000197e0 HealthyU`-[WebViewJavascriptBridge webViewDidFinishLoad:](self=0x0fc20330, _cmd=0x00bce8cb, webView=0x0fcf5c70) + 432 at WebViewJavascriptBridge.m:335
    frame #66: 0x0065cd54 UIKit`-[UIWebView webView:didFinishLoadForFrame:] + 388
    frame #67: 0x0065ec42 UIKit`-[UIWebViewWebViewDelegate webView:didFinishLoadForFrame:] + 56
    frame #68: 0x0219fd1d CoreFoundation`__invoking___ + 29
    frame #69: 0x0219fc2a CoreFoundation`-[NSInvocation invoke] + 362
    frame #70: 0x0219fdaa CoreFoundation`-[NSInvocation invokeWithTarget:] + 74
    frame #71: 0x04cc011d WebKit`-[_WebSafeForwarder forwardInvocation:] + 157
    frame #72: 0x0219b6da CoreFoundation`___forwarding___ + 458
    frame #73: 0x0219b4ee CoreFoundation`_CF_forwarding_prep_0 + 14
    frame #74: 0x0219fd1d CoreFoundation`__invoking___ + 29
    frame #75: 0x0219fc2a CoreFoundation`-[NSInvocation invoke] + 362
    frame #76: 0x05cd2b29 WebCore`HandleDelegateSource(void*) + 121
    frame #77: 0x0213483f CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    frame #78: 0x021341cb CoreFoundation`__CFRunLoopDoSources0 + 235
    frame #79: 0x0215129e CoreFoundation`__CFRunLoopRun + 910
    frame #80: 0x02150ac3 CoreFoundation`CFRunLoopRunSpecific + 467
    frame #81: 0x021508db CoreFoundation`CFRunLoopRunInMode + 123
    frame #82: 0x02f219e2 GraphicsServices`GSEventRunModal + 192
    frame #83: 0x02f21809 GraphicsServices`GSEventRun + 104
    frame #84: 0x0041bd3b UIKit`UIApplicationMain + 1225
    frame #85: 0x0001ecb2 HealthyU`main(argc=1, argv=0xbfffee60) + 130 at main.m:16
    frame #86: 0x01d9f725 libdyld.dylib`start + 1

HTML issue

when i am trying to use the codebase in my project its giving following error
function connectWebViewJavascriptBridge(callback)

connectWebViewJavascriptBridge an anoymous function and there is no data from response callback.

Issue in returning value within a js function

Hi
I have been struggling with an issue for the past few days.The issue is
We have a html page which communicates wih th javascript file teh javascript file in turn communicates with the native ios code of the app using your webview javascript bridge.The problem is
in the following js function we are calling a function of another javascript file

            TheApp.getAppVersion = function()
            {
              var vpbVersion = VestaPhoneBridge.GetUserAgent().version;
              if(vpbVersion != null)
                 {
                   return ""+vpbVersion;
                 }
               return null;
            };

The above method is calling a function in another .js file which is as follows:

   VestaPhoneBridge.GetUserAgent = function(_callback)
    {
       bridge.callHandler('initiateGetUserAgentFunc','test', function(response) 
          {
             //getting response here from native 
           })
   };

The problem is in the function "bridge.callHandler('initiateGetUserAgentFunc','test', function(response) " inside the above function
we are needed to return a value but we need to return the value to VestaPhoneBridge.GetUserAgent instead of "bridge.callHandler('initiateGetUserAgentFunc','test', function(response)"
The problem is we cannot use callback function in js also.The only thing is we have to return a value.
So it would be really great if you could suggest some solution for this problem.

Thanks
Murli Krishna .V

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.