WKWebView fails to load images and CSS using loadHTMLString(_, baseURL:)

前端 未结 10 819
抹茶落季
抹茶落季 2020-12-14 14:05

Apple\'s recommendation:

In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView.

Thus, I have r

相关标签:
10条回答
  • 2020-12-14 14:34

    You can base64 encode the images... I know that works. Not sure if it will be appropriate for your use case though.

    Kind of funny, I just ran into this problem while doing the opposite - moving from base64 encoded to image files.

    0 讨论(0)
  • 2020-12-14 14:36

    Without taking a look at your actual project it's difficult to give some hundreed percent sure advices.

    However:

    class ViewController: UIViewController {
    
        var webView = WKWebView()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            webView.translatesAutoresizingMaskIntoConstraints = false
            let views = [
                "webView" : webView
            ]
            view.addSubview(webView)
            var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: [.AlignAllLeading, .AlignAllTrailing], metrics: nil, views: views)
            constraints.appendContentsOf(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: [.AlignAllTop, .AlignAllBottom], metrics: nil, views: views))
            NSLayoutConstraint.activateConstraints(constraints)
    
            let path = NSBundle.mainBundle().pathForResource("ios - WKWebView fails to load images and CSS using loadHTMLString(_, baseURL_) - Stack Overflow", ofType: "htm")
            let url = NSURL(fileURLWithPath: path!)
            webView.loadHTMLString(try! String(contentsOfURL: url), baseURL: url.URLByDeletingLastPathComponent)
    
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    

    I think the key point here is baseUrl parameter, you should setup it correctly. In my case i've used html's url without last path component - e.g. containing folder. This works fine on both device & simulator - check device snapshot. I've uploaded sample project to https://github.com/soxjke/WKWebViewTest so you can take a look (i've removed codesigning info from git)

    So, to recap - method is working, functionality is working, just you do something wrong with it. To help you get what's wrong with your solutions, i'll add some suggestions: 1. Remember, that simulator filesystem is case-insensitive, device filesystem is case-sensitive. So if you have your filenames in html in lowercase - this won't work on device. 8fFsD.png != 8ffsd.png 2. Remember, that when copying resources, XCode ignores your folder structure. So if your html has <img src="./img/1.png"> and your XCOde project has folder structure like

    test.htm
    
    img/
    
        1.png 
        2.png
    

    After build it will be flattened, so test.htm and 1.png and 2.png will reside on same level

    test.htm
    1.png 
    2.png
    

    I'm almost sure, after you verify these two assumptions, you'll get this method working.

    0 讨论(0)
  • 2020-12-14 14:39

    Well you should be able to use local images and CSS files (and JavaScript files for that matter) with WKWebViews with the function that you have already found. My guess is that the problem is with your baseURL variable.

    Update 7.5.2017:

    I have completely updated the code from another SO answer of mine that used to be linked to my answer here. I have a working project for loadHTMLString() and .loadFileURL()

    0 讨论(0)
  • 2020-12-14 14:43

    Try to create baseURL using:

    let baseURL = URL(fileURLWithPath: "#path#")

    instead of:

    let baseURL = URL(string: "#path#")

    The main difference is that the first method adds file:// prefix before the path.

    0 讨论(0)
  • 2020-12-14 14:53

    I know this is quite old already, but I ran into the exact same problem and it took me hours of trials and even to find this thread with the same problem (Xamarin Forms App)

    My issue was: parsing remote HTML content into a string and also adding locally saved images (also downloaded dynamically, no resource of the app). On the simulator all works well, but on acutal device the local images are not showing (also no ? or anything indicating an error, just a blank frame). The Xamarin webview also offers the "BaseURL" option which didn't help, also not to use the BaseURL on the custom iOS wkWebView.

    The only working solution as pointed out by Scott above, is to write the HTML into a file and then use the "LoadFileUrl" function and allow read access to the base directory. This also works with absolute file paths for images in the HTML (not only relative to the basedir, but of course somewhere within the basedir).

    My custom webview renderer to load web and local content looks like this now:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
        base.OnElementPropertyChanged(sender, e);
        NSUrl baseURL = new NSUrl(App.dirNews, true);
        string viewFile = Path.Combine(App.dirNews, "view.html");
        NSUrl fileURL = new NSUrl(viewFile, false);
    
        switch (e.PropertyName) {
            case "Url":
                System.Console.WriteLine("--- Loading Web page ---");
                System.Console.WriteLine("--- " + Element.Url + " ---");
                NSUrlRequest myRequest = new NSUrlRequest(new NSUrl(Element.Url), NSUrlRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, 120);
                Control.LoadRequest(myRequest);
                break;
    
            case "HTML":
                System.Console.WriteLine("--- Showing HTTP content ---");
                File.WriteAllText(viewFile, Element.HTML, System.Text.Encoding.UTF8);
                Control.LoadFileUrl(fileURL, baseURL);
                break;
        }
    }
    
    0 讨论(0)
  • 2020-12-14 14:54

    I was able to reproduce a similar issue. WKWebView loads my images specially if they are located remotely, apart from my app server.

    For servers that are not SSL-secured (http instead of https), you can set your info.plist as per below:

    App Transport Security Settings
    
     - Allow Arbitrary Loads in Web Content (Set to YES)
     - Allow Arbitrary Loads (Set to YES)
    

    The problem was actually in the server. The server application was either:

    • Changing the image src from "http://IP-or-domain/uploads/file.jpg" to "../../uploads/file.jpg"

    - OR -

    • The image src was "http://localhost/uploads/file.jpg" or "http://127.0.0.1/uploads/file.jpg" instead of "http://YOUR-SERVER-IP-ADDRESS/uploads/file.jpg"

    In these cases, the actual device wont be able to locate the image. This only works with iOS Simulator because the virtual device is the same as the server and development machine. It can read LOCALHOST and 127.0.0.1.

    In my server, I was using a Rich Text Editor (TinyMCE) and it automatically removes the IP address after it detects that it's the same source.

    0 讨论(0)
提交回复
热议问题