It is not possible to load local files from both Caches and Documents directories in the same instance of WKWebView

Originator:designatednerd
Number:rdar://47312604 Date Originated:16-Jan-2019 12:10 PM
Status:Open Resolved:
Product:iOS + SDK Product Version:12.1
Classification:Security Reproducible:Always
 
Summary:
Once you have called `loadFileURL(_, allowingReadAccessTo:)` and passed a particular URL into `allowingReadAccessTo`, that same instance of `WKWebView` cannot read any other URLs.

If you pass in the URL of a single file, trying to load any other single file from anywhere on your filesystem will fail with a security error. You have to create a new instance of `WKWebView` to read any other file. 
You **can** pass the URL of a directory into `allowingReadAccessTo`, but while you can read other items from that directory, you are not able to access other directories without creating a new instance of `WKWebView`.

For example, if you have items in the Caches folder and in the Documents folder depending on whether the user has decided to permanently download these items, you can only show things from one of these directories at a time. 

There is no way to reset the folder the `WKWebView` has access to. Subsequent calls to `loadFileURL(_, allowingReadAccessTo:)` ignore the second parameter, and there is no separate variable to allow the read access directory to change.

Steps to Reproduce:
1. Build app for iPad that involves loading various documents from either Caches, if the user has not indicated they want something permanently downloaded, or Documents, if they indicate they have. 
2. Attempt to set up `loadFileURL` per document, realize once the URL is set it can’t be reset.
3. Attempt to pass in one folder, then realize documents are in different folders based on user preferences. 
4. Attempt to pass in the common parent/grandparent of both folders, but this is the Application’s sandbox directory and doesn’t work at all.
5.  Realize I can’t keep the same web view and wind up just recreating the VC every time on iPad, which seems like a giant waste of processor cycles and memory
6. Have sad

Expected Results:
Explicitly granting read access to a different file or folder actually grants read access to that file or folder, not just for the file or folder passed in when the method is first called.

Actual Results:
Sadness, failure to load, errors, excessive use of expletives. 

Version:
12.1

Notes:
iOS 12.1, Xcode 10.1

Project attached that shows this behavior (and some other stuff related to rdar://47312413). Note that because of the issue noted in the other rdar, this *must* be run on a physical device, or you will not be able to see the behavior change. Recommend comparing behavior on iPhone vs iPad - there’s notes in the app about what expected behavior is for each in each situation. 

As mentioned in step 4: Attempting to pass your application's sandbox directory (which is the direct parent of the user's Documents directory and the grandparent of the Caches directory) doesn't do anything. Even though this is a shared parent of both Documents and Caches, you still receive security errors attempting to load any local file when this is passed in.

Comments

Attached project: https://github.com/designatednerd/FileARadar/tree/master/WKWebViewShenanigans

By designatednerd at Jan. 16, 2019, 11:11 a.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!