I have some attractive graph which is made in HTML and javascript.
So my questions are:
Can I use this work in my swift app,
Can we use javascript and html code to make graph in app?using webview
Can we pass values from swift/objective c code to javascript/html code and vice-versa?
If yes , How can we pass variable value to html/javascript and how to to accept this value in HTML
html text can be embedded into labels as NSAttributedString instances
HTML content that has scripts and stuff can be put into a web view container: UIWebView or WKWebView
YES. Create a webview then load this html page.
YES. (same as answer 1)
YES .
To send to html page: call [webView stringByEvaluatingJavaScriptFromString:function];
To send to swift/objective-c : handle shouldStartLoadWithRequest of your UIwebview.
-(BOOL) webView : (UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType : (UIWebViewNavigationType)navigationType {
if ([[[request URL] absoluteString] hasPrefix:#"yourPrefixe:"]) {
//do your works
//then cancel current request
return NO;
}
return YES;
}
Related
I'm displaying google groups view inside my UIWebView window but it displays the header with options to other google services. Is there a way to hide the header and just display the google groups content ?
This is the URL I'm using ...
https://groups.google.com/d/forum/MyAppGroupName
Use UIWebViewDelegate method webViewDidFinishLoad and run this JS script in
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *script = [NSString stringWithFormat:#"document.getElementById(\"og_head\").style.display='none';"];
[webView stringByEvaluatingJavaScriptFromString:script];
}
I have a webview that can be cycled through different URLs. When I switch from one to the other I want the old web page to disappear before loading the next one. How can I do this without re allocating the webview?
If I try to [self.webView loadHTMLString:#"" baseURL:nil]; and load my URL in the same function the previous web page still remains:
[self.webView loadHTMLString:#"" baseURL:nil];
[self.webView loadRequest:[NSURLRequest requestWithURL:self.pageURL]];
EDIT: this apparently isn't clear enough for you. the below code doesn't clear the webview, it displays the previous page until the new one is loaded:
- (void) startLoadOfNextURL:(NSURL*)url
{
// clear:
[self.webView loadHTMLString:#"" baseURL:nil]; //DOESNT WORK
// Load real next URL
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
You can write the code below while your controller dismisses.
webView.load(URLRequest(url: URL(string:"about:blank")!))
You can make it load a blank page
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
Use JavaScript instead.
webView.evaluateJavaScript("document.body.remove()")
The following code clears the screen and then navigates
Swift
webView.evaluateJavaScript("document.documentElement.remove()") { (_, _) in
self.webView.load(urlRequest)
}
To clear old contents of webview
When you call - loadHTMLString:baseURL: it doesn't block until the load is complete. Once it records your request, it returns and loads in the background.
As a result, you would need to wait for the first load to finish before kicking off a new load request.
With UIWebView you would use UIWebViewDelegate's
- webViewDidFinishLoad:.
With WKWebView you would use WKNavigationDelegate's
- webView:didFinishNavigation:
Another approach if you really wanted to clear the contents without a delegate method would be to use JavaScript (eg https://stackoverflow.com/a/4241420/3352624). Then for UIWebView you could invoke - stringByEvaluatingJavaScriptFromString:. That method will block execution until the JavaScript executes and returns.
For WKWebView, you would need to do something like https://stackoverflow.com/a/30894786/3352624 since its - evaluateJavaScript:completionHandler: doesn't block.
To make old contents "disappear"
If you really just want to make "the old web page to disappear", you could cover the content area of the webview with a blank UIView temporarily. You could hide the contents when you initiate the load and then show the contents using the delegate methods above after the load completes.
Swift
webView.load(URLRequest(url: URL(string: "about:blank")!))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
//Load request or write code here
})
I went to use UIWebView to display dynamic content, instead of doing it natively using UI-elements. Is it possible to trigger native app functions from simply hitting links inside the UIWebView? Example: hitting a link which then switches current View?
Yes, it's possible. In your html, you write a JS to load a URL with a fake scheme such as
window.location = "request_for_action://anything/that/is/a/valid/url/can/go/here";
Then, in your iOS code, assign a delegate to your webView, and in your delegate, handle
webView:shouldLoadWithRequest:navigationType
with something like
if( [request.URL.scheme isEqualToString: #"request_for_action"] )
{
// parse your custom URL to extract parameter, use URL parts or query string as you like
return NO; // return NO, so webView won't actually try to load this fake request
}
--
Just an aside, you can do the other way, let iOS code invoke some JS codes in your html by
using
NSString* returnValue = [self.webView stringByEvaluatingJavaScriptFromString: "someJSFunction()"];
Yes! When the user presses a link, you hear about it in the web view's delegate and can then do whatever you want. Powerful stuff can be done this way.
The web view's delegate is sent webView:shouldStartLoadWithRequest:navigationType:. You analyze what happened, and respond as you wish. To prevent the web view from trying to follow the link (which may be completely fake, after all), just return NO.
In this example from the TidBITS News app, I have a link in the Web page that uses a totally made-up play: scheme. I detect that in the delegate and play:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)r
navigationType:(UIWebViewNavigationType)nt {
if ([r.URL.scheme isEqualToString: #"play"]) {
[self doPlay:nil];
return NO;
}
if (nt == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:r.URL];
return NO;
}
return YES;
}
Implement the UIWebViewDelegate method webView:shouldStartLoadWithRequest:navigationType:.
Handle navigationType and the request as needed.
I have loaded an HTML file from server and displayed that in UIWebview, where it contains an OnClick Function in that file, when the user OnClicks, i will get one Video URL. I want to open that video url in iOS videoplayer. how can i do this? Please help me.
If you have a javascript function which returns the URL when the "Get Video URL" button is clicked like this:
function getVideoURL() {
// do processing to fetch the actual video URL here
window.location = "http://www.domain.com/videos/1";
}
and button handler is set as something like this:
<a target="_blank" href="javascript:getVideoURL();" class="btn-image GetVideo"> </a>
then you will have to provide implementation for UIWebView's following delegate method in your view controller class:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
After this you can use the relative path from the java script request
request.mainDocumentURL.relativePath
inside the delegate to refer to the URL returned from the Java script method. You can use the fetched URL to open iOS video player and play the video as follows:
MPMoviePlayerController* moviePlayer=[[MPMoviePlayerController alloc]initWithContentURL:[NSURL URLWithString: strurl]];
moviePlayer.fullscreen = YES;
[moviePlayer play];
You can use stringByEvaluatingJavaScriptFromString.
But we need to know what onClick function does exactly?
Does it return video URL directly?
Or it modifies HMTL to display that video URL?
If it returns videoURL directly:
NSString *videoURL = [webView stringByEvaluatingJavaScriptFromString:#"document.getElementById("yourElementID").click();"];
If it doesn't, you need to parse the HTML for videoURL after calling onClick function.
I have a UIWebView-based application that is storing some state. I have a native tab bar and upper bar however. What I need is that when I click on the native bar, I persist the data stored in the UIWebView.
To do this, I called evaluateJavaScriptByString to create a JSON object and it does a callback to objective-C via the UIWebViewDelegate protocol.
However, I find that the callback is asynchronous and hence my main transaction happens before the data is loaded.
Any idea how this problem can be solved?
Update: To explain the problem better:-
I have an HTML page with a form that someone puts some data into.
My Tab bar is native.
On the click of a button on the tab bar, I want the data from HTML saved to an Objective-C model, and the view should change to some other view.
What is happening is that once I click the button, the javascript call happens to the page (to create a JSON string to send to Objective-C) and this data does get saved to the obj-c model. However, this happens asynchronously. So my screen changes before the data is loaded into the model. If I refresh the next screen it shows the correct data. I was wondering if there was a way around this.
Note, I know how to call OBjective-C functions from WebViews. We are using JSOBjBridge for that anyway.
Just add something like this #"some_var = MAKE_JSON(); window.location = \"myapp://callback/\" + escape(some_var)" at the end of your javascript code, that you transfer to evaluateJavaScriptByString:
In UIWebView's delegate implement webView:shouldStartLoadWithRequest:navigationType: and catch all urls with myapp:// prefix like this:
- (BOOL) webView: (UIWebView *) webView
shouldStartLoadWithRequest: (NSURLRequest *) request
navigationType: (UIWebViewNavigationType) navigationType {
NSString *url = #"myapp://";
NSString *path = request.mainDocumentURL.relativePath;
NSString *callbackURL = #"callback/";
if ( [path hasPrefix:url] ) {
path = [path substringFromIndex:[url length]];
if ( [relPath hasPrefix:callbackURL] ) {
NSString *json = [path substringFromIndex:[callbackURL length]];
//TODO: Work with json
}
return NO;
}
return [super webView:webView shouldStartLoadWithRequest:request navigationType: navigationType];
}
I didn't test this code, I just written it from scratch, but it should work, I already did it in this way.