2

The local code below loads into a WKWebView a local HTML file (from the app container, not the app bundle).

- (void)loadIndexConteneurWithHash:(NSString *)hash
{
    NSString *fileName = @"index.html";
    NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName;
    NSString *rootContainerDirectoryPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www/v2"];

    NSURL *URL = [NSURL URLWithString:subpath relativeToURL:[NSURL fileURLWithPath:rootContainerDirectoryPath]];

    [[NSURLCache sharedURLCache] removeAllCachedResponses];

    [self.webView loadFileURL:URL allowingReadAccessToURL:URL];



    // This below has the same effect (works on simulator and not on device)

    // NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];

    // [self.webView performSelectorOnMainThread:@selector(loadRequest:) withObject:request waitUntilDone:true];
}

The file url on device is : file:///var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html

And on simulator : file:///Users/<me>/Library/Developer/CoreSimulator/Devices/4A5B9713-6589-4DCA-ABBD-F4FF1246AE43/data/Containers/Data/Application/717B54FD-1344-41D3-8B53-FC0767FFE892/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html

This code works fine on any simulator I've tried (ios 12 / ios 13).

It however does not load the HTML file on the device. When I use the Safari debugger, I see that the webview is on "about:blank".

I have no error at runtime, it just seem to stop executing the loadFileURL silently.

What could I do to solve / investigate on this issue?

EDIT 1

Neither the didFailNavigation nor the didFinishNavigation are called on device...

EDIT 2

Adding this code:

NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(@"%@ exists? %d",URL.absoluteString,[fileManager fileExistsAtPath:URL.absoluteString]);

gives this on device: 2019-10-17 18:42:48.955588+0200 gall-app[881:230671] /var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html exists? 1

So it exists at the expected location. I've also downloaded the app container from the device with XCode and I see the file where it should be.

EDIT 3

After further testing, it seems that [self.webView loadFileURL:... is not working on ios 12 (simulator included) but works on ios 13...

There might be some security rule difference between them?

In my info.plist, I have:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

And my webview is initialized with this code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.webView.UIDelegate = self;
    self.webView.navigationDelegate = self;
    
    self.webView.configuration.preferences.javaScriptEnabled = YES;
    self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
    
    [self.webView.configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
    [self.webView.configuration setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
    
    [self addUserScriptToUserContentController:self.webView.configuration.userContentController];
    
Community
  • 1
  • 1
Żabojad
  • 2,946
  • 2
  • 32
  • 39
  • @rmaddy even `decidePolicyForNavigationAction` is not raised on device while it is raised on simulator... – Żabojad Oct 17 '19 at 17:15
  • The only thing I can think of is to change `[self.webView loadFileURL:URL allowingReadAccessToURL:URL];` to `[self.webView loadFileURL:URL allowingReadAccessToURL:URL.URLByDeletingLastPathComponent];`. – rmaddy Oct 17 '19 at 17:16
  • @rmaddy just tried this and it is the same behavior. It looks like there would be some kind of security thing that prevent this to work on device... My `info.plist` has: ` NSAppTransportSecurity NSAllowsArbitraryLoads NSAllowsArbitraryLoadsInWebContent `. Should I need more? – Żabojad Oct 17 '19 at 17:18
  • @Żabojad In your code, `NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName;` there is a hash value and a `#` in the format specifier also. But I'm not seeing those in your logs which you have provided (also the file name is different) – Midhun MP Oct 17 '19 at 17:31
  • @MidhunMP this part can be ignored, the first file that is loaded is without any "#". `hash` is nil if you prefer... – Żabojad Oct 17 '19 at 19:39

1 Answers1

3

OK I have found "why" it was not working. I changed this:

[self.webView loadFileURL:URL allowingReadAccessToURL:URL];

to this:

[self.webView loadFileURL:URL.absoluteURL allowingReadAccessToURL:rootAppURL];

with rootAppURL being:

NSString *rootappPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www"];
NSURL *rootAppURL = [NSURL fileURLWithPath:rootappPath isDirectory:YES];

And it now works on ios < 13

Żabojad
  • 2,946
  • 2
  • 32
  • 39