Ending Webview and going back to VIew Controller when URL changes - ios

I have a edit photo php script that i want to load in my iOS app. I am calling it through WebView "www.example/com/myTool". When the edit task is complete the webView is moving to homepage of the website. I want when the Edit task is complete then instead of redirecting url to www.example.com/home the webView closes and it moves back to View Controller.
What i can think of solution is - when the URL of webView changes then the webView should close and move back to view controller .. But i don't know how to apply it in code.
import UIKit
class AddPostVC: UIViewController {
#IBOutlet weak var addPost: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
addPost.loadRequest(URLRequest(url: URL(string: "https://new.example.com/pentool")!))
}
}

You need to implement UIWebViewDelegate methods.
Before loading a URL, UIWebView will call, (webView: shouldStartLoadWith request) delegate method.
Compare the URL in request property with your home page URL. If yes, close the web view.
Hope this helps :)

You could do this
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:#"window.location"];
This will get you the url of the current page. Or this
currentURL = currentWebView.request.URL.absoluteString
Credit to https://stackoverflow.com/questions/2491410/get-current-url-of-uiwebview/3654403#3654403

Related

WKWebView in iOS app takes a long time to load

I have a UIView that has a WKWebView as a subview. The web view shows up all right, but it takes a long time (more than a second) to display the HTML document. The document is a local file (an HTML file in the project) so there is no Internet latency, and it's a relatively simple HTML document. The HTML document does have eight small images on it, but there is a similar problem with another HTML document that doesn't have any images.
Here's the code that loads the HTML document into the web view:
override func viewDidLoad() {
super.viewDidLoad()
let localHtmlFile = Bundle.main.url(forResource: "place", withExtension: "html");
let request = URLRequest(url: localHtmlFile!);
webView.load(request);
}
I am using Xcode 9.3, Swift 4.1, and iOS 11.2.
The delay happens every time I go to that screen. If it isn't possible to prevent the delay the first time, is it possible to keep the web view around so that the delay only happens once?
Apparently the delay is caused by the time it takes to make a new instance of WKWebView, not the time it takes to load an HTML document. To avoid that delay I figured out a way to reuse a web view.
First I removed the web view from the storyboard scene so that a new web vew wouldn't be created every time the view was loaded. I made a generic view named container that is the same size that I wanted the web view to be.
Then I made a static variable to keep a pointer to the web view:
static var webView: WKWebView? = nil
In my case this static variable is in a class called GameController.
Next I changed the code to check to see if the static webView variable is nil. If webView is nil, the code creates a new web view and sets the static variable to point to that web view. Then the code programmatically adds the web view as a subview of a container view in the storyboard scene.
To set up the storyboard and write this code I used the explanation on the following web site:
http://www.onebigfunction.com/ios/2016/12/14/iOS-javascript-communication/
The basic code in the view controller for the scene that uses the web view (WebViewController in my code) looks like this:
override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
webView = WKWebView(frame: webFrame,
configuration: config)
GameController.webView = webView
} else {
webView = GameController.webView
}
self.container!.addSubview(webView)
}
In my case, I wanted to send information from JavaScript code in the web view to Swift code in my app, so I had to work more with configurations. I also wanted the web view to be transparent, so I added a statement to do that.
override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "scriptHandler")
webView = WKWebView(frame: webFrame,
configuration: config)
webView.isOpaque = false
GameController.webView = webView
} else {
webView = GameController.webView
webView.configuration.userContentController.removeScriptMessageHandler(
forName: "scriptHandler")
webView.configuration.userContentController.add(self,
name: "scriptHandler")
}
self.container!.addSubview(webView)
}
Originally I only set the script handler when I first made the web view, but that didn't work. Apparently a new view controller object was made each time the scene was loaded, so the old script handler didn't work. This code deletes the script handler that pointed to the old view controller and adds a script handler that points to the new view controller.
Just keep a reference to the ViewController, perhaps in a parent controller, app delegate, or even a singleton/global. It should be somewhat faster on subsequent loads.

webview overlaps with status bar only on first load

The status bar overlaps with the top of my webview, exactly how it looks in this post.
However my situation is different from his, because the overlap is only present at the very first load of the webivew, before any of these things happen:
Things that will make the webview spaced properly:
I switch away from the tab of the webview, and switch back
I press any of the js buttons on the page
I rotate the device
Example vid of 1 and 2 on the list
In the video, it starts with showing wikipedia improperly spaced, but once I press the sidebar button, it fixes the spacing. Then I scroll to stackoverflow.com, it is improperly spaced, but when I scroll away and come back it fixes itself.
I have all of my webviews constrained with Webview.top = Top Layout Guide.bottom
It happens with classes as simple as this:
class testweb: UIViewController {
#IBOutlet weak var webview: UIWebView!
override func viewDidLoad() {
let url = NSURL (string: "https://stackoverflow.com")
let requestObj = NSURLRequest(URL: url!)
webview.loadRequest(requestObj)
}
}
It happened before I added the animation.
It happens in the simulator, on a real device, and on both iOS 8 and 9
Any ideas?

Swift - Opening web view links modally

So I have a web view displaying a page and would like to open any links in a new view controller containing a web view modally (like twitter and Facebook do).
I have worked out how to get the url of the link clicked:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let youClicked = request.URL!
print(youClicked)
return true
}
But haven't managed to work out how I can pass this value into a web view on another page and present that view controller modally as a popover.
Any ideas?
Take a look at SFSafariViewController at Apple Developer Documentation
In order to implement the solution you have to import SafariServices and after that...
Declare an Safari View Controller
let destination: NSURL = NSURL(string: "http://desappstre.com")!
let safari: SFSafariViewController = SFSafariViewController(URL: destination)
Segue from your current view controller to the safari view controller declared on step 1
self.presentViewController(safari, animated: true, completion: nil)
If you need control over HTTP events you can use the SFSafariViewControllerDelegate in your destination view controller.
There isn't an out of the box component which can deal with your need. Instead you have to create your own component:
Create a new UIViewController and place a WKWebView in it (Can be archived by Interface Builder or Code - I usually prefer Interface Builder) . Furthermore create an outlet (e.g. called "webView") for the WKWebView
Create the controller - set the URL and present it
// Create the controller
let controller = storyboard.instantiateViewControllerWithIdentifier("MyCustomWebViewController")
//start loading the URL
controller.webView.loadRequest(request)
// present it
presentViewController(viewController, animated: true, completion: nil)

How to resize a Maxpreps HTML widget to fit the UIWebView?

I am trying to use the Maxpreps widget (http://www.maxpreps.com/widgets/createwidget.aspx) in my app to show school sports updates.
I made a html file in xcode and pasted the code provided from Maxpreps. I created a webview and used the code on the view controller.
#IBOutlet weak var sportsTest: UIWebView!
sportsTest,loadRequest(NSURLRequest(URL: NSURL(fileURLWWithPath: NSBundle.mainBundle().pathForResource("widgetcode", ofType: "html")!)))
The problem is when the code is being shown it wont fit the UIWebView properly.
The issue you are having with the HTML not fitting in the UIWebView is not simple to resolve, but I can give you a hack that will get your content on the screen.
The problem is that the web page from Maxpreps loaded from the URL in their widget isn't designed to fit completely on an iPhone in portrait orientation. However it is a responsive HTML page so that is the good news.
First, you don't need to load the script tag or write an HTML file since all that gives you is a link that you need to click, right? You don't want that link, you want the content of what is behind the link, right? Hopefully!
This view controller implementation should work fine:
import UIKit
class ViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// This will force the UIWebView to downscale and fit your page, but
// it is hacky because 91% of original size might not always be the
// right amount. This is why I said it is hard.
self.webView.scrollView.minimumZoomScale = 0.3
self.webView.scrollView.maximumZoomScale = 2.0
self.webView.scrollView.setZoomScale(0.91, animated: false)
}
override func viewWillAppear(animated: Bool) {
if let url = NSURL(string: "http://www.maxpreps.com/local/team/home.aspx?gendersport=boys,baseball&schoolid=45823724-55bc-4d89-926b-b1974b3d8e36") {
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
else {
println("Failed to create URL")
}
}
}
The above works, but better solutions IMHO would be to:
1) Ask Maxpreps to fix their responsive HTML page so that it renders on an iPhone in portrait orientation
2) Ditch HTML altogether and query the information you need using a REST API if they make one available, and then write a native non-HTML screen
3) Attempt to get a dynamic scaling solution in place that works. These are prone to failure based on my experience
Here is what I see on my simulator when I run it:
Another example:

How do i implement the Search button on Xcode 6

I'm quite new to Xcode. I'm building a basic app that searches a website. Ive got the search button to work with a Go button at the side. How would i make the search button also respond to the search on the bottom right on the keyboard?
#IBAction func didClickGo(AnyObject) {
var text = textField.text
var url = NSURL.URLWithString("http://www.mysite.co.uk/search?controller=search&orderby=position&orderway=desc&search_query="+text)
var request = NSURLRequest(URL: url)
webView.loadRequest(request)
Check out this answer:
https://stackoverflow.com/a/22178145/4014757
First, in your view controller you can assign a delegate for the search bar (probably also your view controller)
searchBar.delegate = this;
Then in your view controller (the delegate), you can override the searchBarSearchButtonClicked method with whatever you want to do when the search button is pressed.
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Hope this is what you're looking for, good luck.

Resources