DELAY issues: how to apply styles immediately or not show loaded webpage until styles are applied? - ios

Technologies Used: XCode 6, iOS8, Swift
I'm loading a webpage in a uiwebview and I'm also appending a new stylesheet to the body of that webpage and overwriting some of its styles. But, there is a delay (maybe 1 second or 2) between when the webpage loads and the styles are applied so you can see the webpage before its restyled. I'm using javascript to append the new styles to the body of the webpage. How can I fix this so that the webpage will only show with the styles are already applied? Here is my code:
import UIKit
class SecondViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var website: UIWebView!
var url = "http://www.fake-website-url.net"
func loadUrl() {
let requestURL = NSURL(string: url)
let request = NSURLRequest(URL: requestURL!)
website.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
website.delegate = self
loadUrl()
}
func webViewDidFinishLoad(website: UIWebView) {
var loadStyles = "var script = document.createElement('link');script.type = 'text/css';script.rel = 'stylesheet';script.href = 'http://fake-url.styles.css';document.getElementsByTagName('body')[0].appendChild(script);"
website.stringByEvaluatingJavaScriptFromString(loadStyles)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Note, I'm using Swift.

What I would do is create a property to store the downloaded page. Then override the property setter to add your custom style sheet after the page is saved to that property. Then finally load it into your Web View.
Hope that makes sense.

Related

How to insert user entered data into a local html document

I'm very new to Swift and I'm struggling a bit with a simple task. I have made a simple app which will launch a local HTML file.
I now want to add a text box that appears, asking the user "Enter IP address". Then, that text will be inserted into the HTML file in 3 different places.
Does anyone have any ideas on this? Or know of a good site which might have some tutorials which relate to this idea? Here's my code so far:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var htmlload: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let htmlpath = Bundle.main.path(forResource: "index", ofType: "html")
let url = URL(fileURLWithPath: htmlpath!)
let request = URLRequest(url: url)
htmlload.load(request)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Swift: How do unit test UIWebView loading?

My app has a basic webview controller to perform some operations. This view in the storyboard is not much besides a wrapper around a UIWebView. The controller itself has various public functions that can be called to load pages in the webview, like so:
class WebViewController: UIViewController, UIWebViewDelegate {
// MARK: Properties
#IBOutlet var webView: UIWebView!
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
loadHomePage()
}
// MARK: Public
public func loadHomePage() {
navigateWebView(to: HOME_PAGE)
}
public func loadSettingsPage() {
navigateWebView(to: SETTINGS_PAGE)
}
public func loadSignOutPage() {
navigateWebView(to: SIGN_OUT_PAGE)
}
// MARK: Private
private func navigateWebView(to url: String) {
let request = URLRequest(url: URL(string: url)!)
webView.loadRequest(request)
}
I'm trying to write unit tests that verify that the proper URL is sent to the loadRequest function of the webview. Note that I don't actually care about loading the URL; this is just a unit test, so all I really want to test is that loadSettingsPage sends a URLRequest with the SETTINGS_PAGE URL to the webview to load, for example.
I tried something like this, with no success:
_ = webViewController.view // Calls viewDidLoad()
XCTAssertEqual(webViewController.webView.request?.url?.absoluteString, HOME_PAGE)
The value of the first part of the assertEqual was nil.
I assume I need to mock out the webView somehow but I'm not sure how to go about that. Any suggestions?
As a follow-up, I'd also like to be able to test when things like webView.reload() and webview.goBack() are called, so any pointers there would be appreciated as well. Thanks!

How to show a preview for web url contents when web address is typed in Textbox using Swift 3.0?

Scenario:
Creating a social network app type application, when user type the web address or valid url in the text area my app should identify the valid url,then I have to do the following tasks,
1) If it is a valid web url then automatically show the preview of the web contents in the preview section.
2) Share button should not be enabled until the preview is fully loaded, if not there are some chances that URL alone may be posted instead of the web contents.
What I have tried?
Created a Text view and a preview WebUI view, I used following code to identify the valid URL, if valid url then I am showing the web view and loading the web page.
Code what I tried:
class CommentsViewController: UIViewController {
#IBOutlet weak var comments: UITextField!
#IBOutlet weak var preview: UIWebView!
#IBOutlet weak var btnShare: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
preview.isHidden = true
btnShare.isEnabled = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func valueModified(_ sender: Any) {
//Load web preview only after Check for Valid Web URL
if verifyUrl(urlString: comments.text) == true {
preview.isHidden = false
preview.loadRequest(URLRequest(url: URL(string: comments.text!)!))
btnShare.isEnabled = true
}
}
//Check for Valid Web URL
func verifyUrl (urlString: String?) -> Bool {
//Check for nil
if let urlString = urlString {
// create NSURL instance
if let url = NSURL(string: urlString) {
// check if your application can open the NSURL instance
return UIApplication.shared.canOpenURL(url as URL)
}
}
return false
}
}
What I need exactly?
I do not want to load the web page, I have to load the preview of the page.
Share button should be hidden until the preview is fully loaded.
Screen shot of my code output:
Screen shot of what I am expecting:

Cannot load/scroll full pdf in swift WebView.

I am trying to load a pdf using web view using swift. It can load only one page of the pdf, cannot scroll down more than one page. What can i do?
import UIKit
class ViewController: UIViewController,UIWebViewDelegate {
#IBOutlet var webViews: UIWebView!
var path = ""
override func viewDidLoad() {
super.viewDidLoad()
path = NSBundle.mainBundle().pathForResource("ibook", ofType: "pdf")!
let url = NSURL.fileURLWithPath(path)
/*webViews.scalesPageToFit = true
webViews.scrollView.scrollEnabled = true
webViews.userInteractionEnabled = true*/
webViews.delegate = self
self.webViews.loadRequest(NSURLRequest(URL: url!
))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func webViewDidStartLoad(webView : UIWebView) {
//UIApplication.sharedApplication().networkActivityIndicatorVisible = true
println("webViewDidStartLoad")
}
func webViewDidFinishLoad(webView : UIWebView) {
//UIApplication.sharedApplication().networkActivityIndicatorVisible = [enter image description here][1]false
webViews.scalesPageToFit = true
webViews.scrollView.scrollEnabled = true
webViews.userInteractionEnabled = true
println("webViewDidFinishLoad")
}
}
I've bumped into the similar problem while trying to display external pdf (not the bundled one), but I suppose you can use the same fix.
In your webViewDidFinishLoad, check if the url is actually a pdf one. Because in my case I know what I'm expecting, I used simple dumb checking. If url links to a pdf, you need to reload the web view to show it correctly and hence be able to scroll.
Here is a bit simplified code in objective C. It should be quite similar in Swift. Try something like this:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
static BOOL isPdfReloaded = NO;
if (!isPdfReloaded && [webView.request.URL.absoluteString containsString:#".pdf"])
{
[webView reload];
isPdfReloaded = YES;
}
else
{
isPdfReloaded = NO;
}
}
The Best solution is to migrate from UIWebView to WkWebView

Attempting to load Webview with PDF, receiving link from Parse

I am attempting to load a lunch menu PDF into a web view for a high school app that I am updating. Currently, it can load a PDF into the web view and display it just fine, but I want to speed up the monthly update process by having my app receive the link through Parse (Which I can update much quicker than updating the link in the app itself with Apple's 7 day review period), and then load the PDF. Currently, with what I have put together, my app will not load the PDF. Here's the entire view:
import UIKit
class AlaCarte_ViewController: UIViewController {
#IBOutlet weak var webviewAlaCarte: UIWebView!
var urlpath = String()
func loadAddressUrl(){
let requestURL = NSURL (string:urlpath)
let request = NSURLRequest(URL: requestURL!)
webviewAlaCarte.loadRequest(request)
alaCarteUpdate()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
clearPDFBackground(self.webviewAlaCarte)
}
func clearPDFBackground(webView: UIWebView) {
var view :UIView?
view = webView as UIView
while view != nil {
if NSStringFromClass(view?.dynamicType) == "UIWebPDFView" {
view?.backgroundColor = UIColor.clearColor()
}
view = view?.subviews.first as! UIView?
}
}
func alaCarteUpdate() {
var query = PFQuery(className: "AlaCarte")
query.getObjectInBackgroundWithId("rT7MpEFySU") {(AlaCarte: PFObject!, error: NSError!)-> Void in
if error == nil && AlaCarte != nil {
println(AlaCarte)
} else {
println(error)
}
let AlaCarteLink = AlaCarte["webaddress"] as! String
self.urlpath = AlaCarteLink
}
}
override func viewDidLoad() {
super.viewDidLoad()
loadAddressUrl()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
The link is stored in my Parse app as "webaddress" and does not contain end quotations. Adding them does not help. Any ideas?
It looks to me like you're not telling the web view to load the URL once it's retrieved from Parse.
Try adding the following lines after self.urlpath = AlaCarteLink in alaCarteUpdate().
let requestURL = NSURL (string:self.urlpath)
let request = NSURLRequest(URL: requestURL!)
self.webviewAlaCarte.loadRequest(request)
I think it would also be a good idea to add a function that specifically loads a url string into your web view, so you can call it from both inside alaCarteUpdate(), and loadAddressUrl(), and avoid the duplicate 3x lines. I've assumed that you're loading the URL in loadAddressURL() so that you can show a local/cached document while retrieving the latest from Parse.

Resources