Transferring a javascript variable to to Objective C (IOS) - javascript

I am working on creating an app and am a relatively new Objective C programmer. On a page, "test.php", I have a javascript variable. Here is a simplified version.
<script>
var idx = 45;
document.write(idx);
</script>
I would like to be able to view the value of the variable "idx" in my IOS app, which I have created using Xcode. What would be the optimal way to connect to the page, test.php, and transfer my Javascript variable to Objective C so I could use it as part of my IOS App?
Any help would be greatly appreciated. Thank you.

You will need to communicate between the webview and the native code using a combination of two pieces. First, you will need to "trigger" the webview into returning some value by calling stringByEvaluatingJavaScriptFromString: on the webview. When the webview tries to navigate because of the javascript call, you can intercept it on the native side with the WebView's shouldStartLoadWithRequest: method.
For details, see the specifics here Invoke method in objective c code from HTML code using UIWebView
That is only if you need some activity in the webview to trigger the fetch (or notify the native code that the value has been set). If the value is always available via JS, you can simply use stringByEvaluatingJavaScriptFromString: as follows:
NSString *returnvalue = [self.webviewForHtml stringByEvaluatingJavaScriptFromString:#"var idx = "return_value";return idx;"];

Related

Execute javascript without webview in Android

I'm trying to execute a JS fonction in my Android app.
The function is in a .js file on a website.
I'm not using webview, I want to execute the JS function because it sends the request i want.
In the Console in my browser i just have to do question.vote(0);, how can I do it in my app ?
UPDATE 2018: AndroidJSCore has been superseded by LiquidCore, which is based on V8. Not only does it include the V8 engine, but all of Node.js is available as well.
You can execute JavaScript without a WebView. You can use AndroidJSCore. Here is a quick example how you might do it:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://your_website_here/file.js");
HttpResponse response = client.execute(request);
String js = EntityUtils.toString(response.getEntity());
JSContext context = new JSContext();
context.evaluateScript(js);
context.evaluateScript("question.vote(0);");
However, this most likely won't work outside of a WebView, because I presume you are not only relying on JavaScript, but AJAX, which is not part of pure JavaScript. It requires a browser implementation.
Is there a reason you don't use a hidden WebView and simply inject your code?
// Create a WebView and load a page that includes your JS file
webView.evaluateJavascript("question.vote(0);", null);
For the future reference, there is a library by square for this purpose.
https://github.com/square/duktape-android
This library is a wrapper for Duktape, embeddable JavaScript engine.
You can run javascript without toying with WebView.
Duktape is Ecmascript E5/E5.1 compliant, so basic stuff can be done with this.

How can you access javascript variables from a C#.Net Webbrowser object?

I want to create a Webbrowser .Net object from my C#.Net Winform application and then be able to access javascript variables.
Basically I want to take some action in my main Winform application depending on some user interactions that happen that set javascript variables.
Any advice on how I can make calls to the Webbrowser object to do this?
Note I did look at the Document property that lets you get at the DOM but don't understand how/if that can be used to get at javascript variables.
Dan
In the WinForms browser, use the ObjectForScripting property to handle two-way communications between your WinForms application and your WebBrowser's Document.
You can invoke javascript members from C# through the Document object:
// C# code
webBrowser1.Document.InvokeScript("test",
new String[] { "called from client code" });
Assigning ObjectForScripting as
// C# code
webBrowser1.ObjectForScripting = obj;
appears to allow the hosted javascript to call members of obj, e.g.
// javascript code
window.external.SomeMethod('called from script code');
// executes obj.SomeMethod(string) in C#
Disclaimer: I only have experience with the WPF web browser, so I haven't verified the above myself.
Make use of CeSharp, a Chromium Embedded Framework that allows much more control over your webbrowser component.
To get started
Fire up a VS project
Open nuget console and execute: Install-Package CefSharp.WinForms if you are doing Winforms C# App.
Restart your Visual studio and re-load project.
Example of CefSharp code to get started.
Add a toolStripContainer to your form from the toolbox then use the following example code to load cefsharp browser component.
public Form1()
{
InitializeComponent();
var browser = new ChromiumWebBrowser("http://localhost:1071/");
browser.Dock = DockStyle.Fill;
toolStripContainer1.ContentPanel.Controls.Add(browser);
}
This should get you started, in order to talk to JS from C# you will need to make use of EvaluateScript interface.
Take a look at the following resource.
https://github.com/cefsharp/CefSharp/issues/368

UIWebView Javascript Window to Window Communication

I'm working on an iOS app in which I'm trying to use UIWebView to display a variety of websites. Recently I finished logic to inject Javascript into the UIWebView to catch instances of window.open, window.close, and window.opener.focus. In short, to do so, I inject JS that overrides the aforementioned JS functions, which includes creating an iframe with a specific scheme that I can catch in the app's webView:shouldStartLoadWithRequest:navigationType method. This is all working OK for now, including window.open creating a new UIWebView rather than loading in the same window.
Now though, the issue has come up where there's no feasible solution for JS communication between windows. If the child window tries to call to window.opener or window.parent, it's always returning a null value, and thus, it can't communicate back to the original web view.
In an effort to see what iOS browsers are able to effectively perform window-to-window communication, I found that of the 9 browsers I have on my iPhone, only Safari was able to effectively perform this communication successfully. This leads me to believe that there's something with UIWebView that prevents full JS window-to-window communication from being possible.
Has anyone had any success with getting UIWebView to fully integrate with all JS logic, namely window-to-window communication? Or have proof that JS window-to-window communication isn't possible? Any direction or advice is appreciated. Thanks!
Found possible solution.
Add JavaScriptCore.framework to Linked Frameworks and in your webViewDidFinishLoad:
JSContext *parentCtx = [self.parentWebView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
JSContext *childCtx = [self.childWebView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
childCtx[#"window"][#"opener"] = parentCtx[#"window"];
Now when you call window.opener.test() from childWebView, it will fire test function in parentWebView!
I'm not sure about private API.
Works on iOS 7 only
Swift version
import JavaScriptCore
let jsContextA = webA.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext")
let jsContextB = webB.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext")
//Original objc code : jsContextB[#"window"][#"opener"] = jsContextA[#"window"];
jsContextB!.setObject("opener", forKeyedSubscript: "window")
jsContextB!.setObject(jsContextA!.objectForKeyedSubscript("window"), forKeyedSubscript: "opener")

Android: Calling javascript from WebView

We're coding an app for Android. It's a WebView that contains Html5 pages. We're using loadUrl() webview's method, in order to push some native OS variables to html, such as:
webview.loadUrl("javascript:myJavascriptFunc('" + myAndroidOSVar + "');");
It works pretty fine. But if we are typing on an input from page while loadUrl() is called, we lose focus of our input fields, even if javascript function called just changes a flag on cache.
Do you know other way to call a Javascript function from WebView instead of loadUrl()?
This is the closest you can get to avoiding the issue: WebView hides soft keyboard during loadUrl(), which means a keyboard cannot stay open while calling javascript
Basically you are avoiding the loadUrl call by queuing up commands on the native side and at an interval letting the JS bridge get the commands and execute using JS eval() or something.
I'm not sure exactly how it will respond if you have multiple fields in the webview, but I came up with a workaround to keep the keyboard shown: https://stackoverflow.com/a/18776064/513038. It may be worth trying.
yes, there is a way by adding a JavaScriptInterface to your WebView , refer this tutorial for more explanation and details

do external javascript on a website objective C

This is my first post so I am sorry for any mistakes I made :)
I know the title is confusing, but i will try to explain what I want.
I got this website, on the website there is a schedule, this schedule change when you change different values so that it consist with the appropriate person. When you change a value a JavaScript function is called. Is there any way for me to do this JavaScript (on a site I don't own) from objective-C.
So, what I want is this (in a very plain description):
do JavaScript call change() on website: "My website" (I know this is not valid, but this is what I want)
Also I would like to be able to change the different values and pass the function with parameters.
Thanks
Kristian
The website is here (Norwegian):
http://www.novasoftware.se/webviewer/(S(mfq2npum0th2lxb0g5oy3045))/design1.aspx?schoolid=60810&code=545354&type=3&id=1559)
Edit:
Hello I found another way to solve my problem.
The website is automatically generating an image for each of the students. The url of an image is similar to this link
(had some problems posting the URL)
Where you got &week=42 (you can change this to whatever you want and it works perfect). So I got it working for the MAC (in Safari 5).
But when I try to use this URL in the iPhone simulator I only get a white screen.
this is the code i use:
[webView loadRequest:[NSURLRequest
requestWithURL:[NSURL
URLWithString:#"http://www.novasoftware.se/ImgGen/schedulegenerator.aspx?format=png&schoolid=60810/nb-no&type=3&id={76C567C0-161E-42C3-B054-8941DDD04F52}&period=&week=42&mode=0&printer=0&colors=32&head=0&clock=0&foot=0&day=0&width=1405&height=683&maxwidth=1405&maxheight=683"]]];
It works if I use a simpler URL like "http://www.google.com" :S Does the iPhone not support for aspx?
I only know this in the context of iPhone APIs...
Assuming you have the page loaded in a UIWebView inside your app...
You can call UIWebView method stringByEvaluatingJavaScriptFromString: to send javascript to the page.
If the calling function returns anything, it will be typecast as a NSString and returned to your app, but in your case it looks like you can just ignore the return value. You might need to make your Javascript look something like:
(function(){
change();
return "hello world";
})();
because I'm not sure how well it handles void return values.

Categories

Resources