Passing data from HTML to OF in ofxiPhoneWebViewController

Hi,

Looking for advice from C++/Obj-C experts, I’m extending the awesome fork of ofxiPhoneWebViewController by @pelayo which had the beginnings of an HTML to OF bridge.
https://github.com/pelayomendez/ofxiPhoneWebViewController

What’s a clean way to pass data? Still new to C++, everything feels like a minefield of memory leaks… :wink:

How it works:
In the HTML page you’d use the URL for parameters:

<a href="of://callOFfunction/functionName?foo=bar">Call OF</a>

Here’s the modified ObjC code:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    if ([[request.URL scheme] isEqual:@"of"]) {
        
        if ([[request.URL host] isEqual:@"closeWindow"]) {
            delegate->hideView(YES);
            delegate->didCloseWindow();
        }
        if ([[request.URL host] isEqual:@"openInBrowser"]) {
            NSString *url = [request.URL query];
            NSLog(@"openInBrowser url:%@", url);
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString: [[[NSString alloc] initWithString: url] autorelease] ]];
        }
        else if ([[request.URL host] isEqual:@"callOFfunction"]) {
            
            // Here's what I added:
            
            // contains ["/","myFunctionName"]
            NSArray *components = [request.URL pathComponents];
            
            // contains "myFunctionName"
            string functionName = [[components objectAtIndex: 1] cStringUsingEncoding:[NSString defaultCStringEncoding]];
            
            // contains "foo=bar"
            string query = [[request.URL query] cStringUsingEncoding:[NSString defaultCStringEncoding]];
            
            delegate->callExternalFunction(functionName, query);
            
        }
        return NO; // Tells the webView not to load the URL
    }
    else {
        return YES; // Tells the webView to go ahead and load the URL
    }
}
  • What makes more sense, passing C strings by value or NSString pointers?

  • I’m assuming in C++ you can’t dynamically evaluate members by string, right?
    So eventually in the event listener in your OF app you’d have something like

     if( args.functionName == "doSomething" ) doSomething( args.query );
    
  • Maybe using the path instead of the query would be nicer, like of://callOFfunction/functionName/param1/param2

Any suggestions welcome!

2 Likes

Hey I’m trying to make this too.
Have you made any progress since then?

What I did not understand what is the scope of the external function that we’re trying to call.

this ofNotifyEvent can call functions of my main application?

void ofNotifyEvent(EventType & event, ArgumentsType & args, SenderType * sender){
    try{
        event.notify(sender,args);
    }catch(ofEventAttendedException & e){

    }
}

UPDATE

haha, finally I understood! It’s really simple:

All the process is over ofNotify that sends triggers by state. And them this method below makes the call for external functions.

void testApp::webViewEvent(ofxiPhoneWebViewControllerEventArgs &args) {
    if(args.state == ofxiPhoneWebViewStateDidStartLoading){
        NSLog(@"Webview did start loading URL %@.", args.url);
    }
    else if(args.state == ofxiPhoneWebViewStateDidFinishLoading){
        NSLog(@"Webview did finish loading URL %@.", args.url);
    }
    else if(args.state == ofxiPhoneWebViewStateDidFailLoading){
        NSLog(@"Webview did fail to load the URL %@. Error: %@", args.url, args.error);
    }
    else if(args.state == ofxiPhoneWebViewCalledExternalFunction){

        NSLog(@"SetParam: %@", args.param);
        
        if(ofxNSStringToString(args.param)=="function1"){
            this->function1();
        }else if(ofxNSStringToString(args.param)=="function2"){
            this->function2();
        }
    }
}

Hi, yes you’re right! The term ‘call’ is a bit misleading, you’ll need conditionals based on the string parameter.

Answering my own old questions:

What makes more sense, passing C strings by value or NSString pointers?

Use std:string.
There’s a couple of helpers in ofxiOSExtras for converting types, such as
ofxiOSNSStringToString( NSString *s );
Seems to make sense to keep ObjC and C++ separate.

I’m assuming in C++ you can’t dynamically evaluate members by string, right?
So eventually in the event listener in your OF app you’d have something like
if( args.functionName == “doSomething” ) doSomething( args.query );

Yes.

Maybe using the path instead of the query would be nicer, like of://callOFfunction/functionName/param1/param2

I kept using the query, otherwise there’s issues with characters like ‘/’ ‘?’ and ‘&’.

Hope that helps!

Cheers

1 Like