6

I have a WKWebView that works in Simulator perfectly but why runs in the device only a white empty screen appear this is my code:

override func loadView() {
    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.preferences.setValue(true, forKey:"allowFileAccessFromFileURLs")
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    view = webView
}

override func viewDidLoad() {
    super.viewDidLoad()

    let path2Esferas = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)/virtualtour.html")
    let url =  URL(fileURLWithPath: path2Esferas) 
    //NSURL.fileURL(withPath: path2Esferas)

    let myRequest = URLRequest(url: url)
    webView.load(myRequest)
}

The HTML in "path2Esferas" is in a cache's folder that I load previously, if I put a different URL like let myURL = URL(string: "https://www.apple.com") as docs show, it works correctly in simulator and device. Eg: http://proyectoshm.com/esferas/real_de_mina/realdeminas.html

mugx
  • 9,869
  • 3
  • 43
  • 55
Hugo Fortis
  • 429
  • 1
  • 3
  • 16
  • Is `\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)/virtualtour.html` a local file? – mugx Dec 17 '17 at 02:50
  • Yes, logs shows: `2017-12-16 20:53:09.118469-0600 Urbania[295:8595] [MC] Lazy loading NSBundle MobileCoreServices.framework 2017-12-16 20:53:09.119302-0600 Urbania[295:8595] [MC] Loaded MobileCoreServices.framework /var/mobile/Containers/Data/Application/4FD08717-7269-48C1-8E13-ACA134F71839/Library/Caches/repository/esfera/127/virtualtour.html` – Hugo Fortis Dec 17 '17 at 02:53
  • When is that webview displayed ? It has to be visible in a window to render its content. That part may be faster on simulator (?) – nstefan Dec 21 '17 at 11:18
  • Doesn't matter when, the main problem is download an html and then load it inside the WKWebView. In the meantime, I asked Hugo to change the title. – mugx Dec 21 '17 at 11:45
  • Did you try in iphone 6 and above ??? It will work fine – jakir hussain Dec 26 '17 at 07:18
  • Going to check that – Hugo Fortis Dec 27 '17 at 19:21

7 Answers7

0

INTRO

My solution is NOT solving the full problem.

I leave it here temporary might be useful for understanding (mostly from our comments below) what did not work.


import UIKit
import WebKit

class ViewController: UIViewController {
  var webView:WKWebView?

  override func viewDidLoad() {
    super.viewDidLoad()

    let webConfiguration = WKWebViewConfiguration()
    self.webView = WKWebView(frame: self.view.frame, configuration: webConfiguration)
    // http request with URLRequest.CachePolicy.returnCacheDataElseLoad
    let request = URLRequest(url: URL(string:"http://proyectoshm.com/esferas/real_de_mina/realdeminas.html")!, cachePolicy: URLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: 10)
    self.webView?.load(request)
    self.view.addSubview(self.webView!)
  }
}

I also added into the plist:

App Transport Security Settings > Allow Arbitrary Loads in Web Content > YES App Transport Security Settings > Allow Arbitrary Loads > YES

eventually to be able to submit on the store your app, you will have some trouble since:

Apple announced that ATS will be REQUIRED of all apps as of January 2017.

https://forums.developer.apple.com/thread/48979

enter image description here

result is:

enter image description here

mugx
  • 9,869
  • 3
  • 43
  • 55
  • Ask for url `String(contentsOf:)` `let fileContent = try! String(contentsOf: url)` `webView.loadHTMLString(fileContent, baseURL: nil)` But, the same result – Hugo Fortis Dec 17 '17 at 03:00
  • try to remove this line: `webConfiguration.preferences.setValue(true, forKey:"allowFileAccessFromFileURLs")` – mugx Dec 17 '17 at 03:01
  • i put that because of this: [link](https://stackoverflow.com/questions/46996292/ios-wkwebview-cross-origin-requests-are-only-supported-for-http) , but i tried removing it but nothing. – Hugo Fortis Dec 17 '17 at 03:04
  • try last time, check again the edit with: `let fileContent = try String(contentsOfFile: path, encoding: .utf8) ` – mugx Dec 17 '17 at 03:29
  • No :( , In fact is not working in the simulator neither , thanks. – Hugo Fortis Dec 17 '17 at 03:46
  • I made a test project with an `example.html`, tested on the device and on simulator, working perfectly. Check the edit. – mugx Dec 17 '17 at 04:01
  • Working from Bundle but from Caches Directory no. `let local = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0] let urlLocal = URL(fileURLWithPath: local) let path2Esferas = urlLocal.appendingPathComponent("repository/esfera/127/index.html")` – Hugo Fortis Dec 17 '17 at 17:26
  • try again with this: `let filepath = (NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first ?? "").appending("/repository/esfera/127/index‌​.html") let fileContent = try String(contentsOfFile: filepath, encoding: .utf8) self.webView?.loadHTMLString(fileContent, baseURL: nil)` – mugx Dec 17 '17 at 21:31
  • i give up, now i can read a simple HTML like yours but mi content is not displaying, i think is something about performance configuration in device, because html simple works, the weird thing is that from bundled works, but from Cache no, i'm going to look for the old a trusted UIWebView instead. Thanks for all your time Andrea – Hugo Fortis Dec 18 '17 at 18:17
  • This is the type of content that we wanna load [http://proyectoshm.com/esferas/real_de_mina/realdeminas.html](http://proyectoshm.com/esferas/real_de_mina/realdeminas.html) – Hugo Fortis Dec 18 '17 at 18:20
  • going to test it – mugx Dec 18 '17 at 18:42
  • 1
    do you have this: `App Transport Security Settings > Allow Arbitrary Loads in Web Content > YES` in your plist ? https://stackoverflow.com/questions/32456848/ios9-does-not-load-insecure-resources-from-a-secure-page-ssl-https – mugx Dec 18 '17 at 18:51
  • I suggest you don't use UIWebView, https://developer.apple.com/documentation/uikit/uiwebview since Apple says: `In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView.` so may be deprecated soon. – mugx Dec 18 '17 at 19:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/161484/discussion-between-hugo-fortis-and-andrea-mugnaini). – Hugo Fortis Dec 19 '17 at 00:12
0

The problem is this phrase:

frame: .zero

Supply some frame, even if it is a dummy value:

frame: CGRect(x:0, y:0, width:100, height:100)
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 2
    Since on Simulator is working fine, why should be frame: .zero the problem? As far as we know, the problem is the impossibility (blank screen) to load cached html inside the WKWebView. With cached Hugo means, html downloaded in a local file (the html is something similar to this one: http://proyectoshm.com/esferas/real_de_mina/realdeminas.html, they need to load it offline). Apparently, the same process (html fetching+loading) is working fine with the UIWebView. So we are guessing might be an issue related to the WKWebView itself. – mugx Dec 21 '17 at 00:31
0

If I've understand from comments and from your code (Path.localPath should be related to your local resources..) you have to do with local files. I remember it should be related to your wrong method to load the local resource to the WkWebView. In fact , since iOS 9.0+, as explained to the docs you can use the instance method loadFileURL(_:allowingReadAccessTo:)

You should also try with loadHTMLString:

let path2Esferas = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)/virtualtour.html")
let folderPath = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)")
let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
do {
     let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
     webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
} catch {
  // catch error
}

P.S. Be sure that your local html/JavaScript/CSS files added in Project -> Target -> Build Phases -> Copy Bundle Resources

Anyway, remember you can load your local resources only after their download was completed, so if you have an asynchronous download be sure you have finish it to use this code.

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • Requirement is: that file has to be downloaded and cached, so can't be loaded from the main bundle. Quoting Hugo: `"path2Esferas" is in a cache's folder that i load previously` – mugx Dec 21 '17 at 11:13
  • Umh that's correct about main bundle. But about local resources it should be loaded as docs or as my example. – Alessandro Ornano Dec 21 '17 at 11:19
  • Yes correct, that was also my first solution for Hugo. I also tried to load his website and was working fine, but this is not enough. He requires to `download` the file first, and then `load` that file into the WKWebView – mugx Dec 21 '17 at 11:24
  • I suspect he try to load contents before the download have finished..but we haven't enough code in his question to declare it. – Alessandro Ornano Dec 21 '17 at 11:26
  • In theory this could be a possible problem. But he said above that the same stuff is working fine with the UIWebView (both device and simulator), and is also working fine with the WKWebView on the simulator (but `Not` on the device) – mugx Dec 21 '17 at 11:28
0

Instead of hacking WKWebViewConfiguration with setting private API flag allowFileAccessFromFileURLs, try loading a file URL with a special file URL method:

self.webView?.loadFileURL(url, allowingReadAccessToURL: url.deletingLastPathComponent)
Eugene Dudnyk
  • 5,553
  • 1
  • 23
  • 48
0

Have you tried changing your line

let myRequest = URLRequest(url: url)

to

let myRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 100)
ZameerMoh
  • 1,149
  • 1
  • 17
  • 26
0

Please check your network connection, if you are a different network with html file you can not see anything

0

After more than 1 year I found the solution, we need to use loadFileURL to have access to the local resources, here is my working code with WKWebView, plus instead of load I use loadHTMLString. vistaweb in my WebView BTW

Thanks to this answer : Load local web files & resources in WKWebView

        do {

            let local = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
            // Loading: Library/Caches/repositorioLocal/esferas/znvUifZhH8mIDr09cX8j/index.html
            let resourceFolder = "repositorioLocal/esferas/znvUifZhH8mIDr09cX8j"
            let fileToLoad = "index.html"

            let urlToFolder = URL(fileURLWithPath: local).appendingPathComponent(resourceFolder)
            let urlToFile =  URL(fileURLWithPath: local).appendingPathComponent(resourceFolder).appendingPathComponent(fileToLoad)
            let fileContent = try String(contentsOf: urlToFile)

            let webConfiguration = WKWebViewConfiguration()
            webConfiguration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
            webConfiguration.allowsInlineMediaPlayback = true

            vistaweb = WKWebView(frame: self.view.frame, configuration: webConfiguration)
            self.vistaweb.loadFileURL(urlToFolder, allowingReadAccessTo: urlToFolder)
            self.vistaweb.loadHTMLString(fileContent, baseURL: urlToFile)
            self.view.addSubview(vistaweb)

        } catch let error {
            print("Error: \(error.localizedDescription)")
        }
Hugo Fortis
  • 429
  • 1
  • 3
  • 16