Loading document in shared documents folder into WKWebView - ios

I am having problems trying to load a document into a WKWebView when the document has been added to the app using iTunes file sharing.
If I include the file inside the app I can load it fine.
I am using this code to get the load the file:
let documentsURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fooURL = documentsURL.appendingPathComponent(docFileName)
let docURL = URL(fileURLWithPath: fooURL.path)
let req = URLRequest(url:docURL)
docView!.load(req)
docURL looks like this:
file:///var/mobile/Containers/Data/Application/432E716E-F70D-4985-814C-FFE7ECE53EF8/Documents/filename.pdf
I have tried to check the file exists using this code:
FileManager().fileExists(atPath: fooURL.path)
This returns true. I have also tried to copy the file from the documents folder into the app folder but this returns an error of file not found (again this is even after checking the file exists)
Should WKWebView be able to load from this location? Or have I missed something here?

Perhaps you are looking for loadFileURL(_:allowingReadAccessTo:)
Though I didn't see it explicitly stated in the docs, it wouldn't surprise me if the security policies of WKWebView are getting in your way, and the presence of this method alone seems to confirm that ;-)
Happy coding!

Related

Text file can't be created inside a folder

I'm trying to create a log.txt file inside a folder of a device, but I get this error:
NSCocoaErrorDomain Code=512 "The file “log.txt” couldn’t be saved in
the folder “Logs”.
The folder Logs already exists on the device, but I still get this error. Please find my code below:
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let logPath = path.appendingPathComponent("Logs").appendingPathComponent("log.txt")
try! "Hello world".write(to: logPath, atomically: true, encoding: .utf8)
However, if I replace the logPath with path.appendingPathComponent("log.txt"), it will work, BUT it creates the file outside of the folder Logs instead of inside.
How can I solve this?
I have fixed this problem by using the new function called appending(component:_) of the FileManager API.
The old one that I used in my question was not deprecated, but it did not work, and I still have no idea.
However, using the new one above makes everything works just fine.

Are UserDefaults and ApplicationSupportDirectory safe against external manipulation?

I use standard UserDefaults and default applicationSupportDirectory:
userDefaults.set(level, forKey: solvedLevel)
let fileURL = try FileManager.default
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("somethingToSave.json")
try JSONEncoder().encode(myObject)
.write(to: fileURL)
I'm wondering if these files are safe against external manipulation. Is a user (with and without jailbreak) able to change the content of the files for example to change the current level or the json file?
For Application Support Directory I found that the content is not visible for users (I suggest that that's only true for no jailbreak?).
For User Defaults I only found the "Sandbox Considerations" here. But I guess that's only true for non jailbreaked devices, too?

Get Reference to SceneKit Catalog Swift

I must be missing something simple - I'm trying to iterate through the
files in an .scnassets folder but can't seem to get a reference to the
folder/catalog.
Here's the organizer:
Models.scnassets contains one file. I tried this:
let fileManager = FileManager.default
let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
let docsURL = urls.first
let assetFolderPath = docsURL?.appendingPathComponent("Models.scnassets").path
And I tried this and several other variants:
let modelPathString = "ARAds/Models.scnassets"
Then I attempted to count the files with both of the above paths:
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: assetFolderPath!)
//or modelPathString
print(modelPathDirectoryFiles.count)
} catch {
print("error getting list of files")
}
I get the error message in all cases.
I assume there must be some special way to get a reference to a SceneKit
Catalog but I have not been able to find that in the Apple docs nor SO.
Any guidance would be appreciated. iOS 11.4 Xcode 10.0
Looking at your code, the first thing I see, is that you are referencing the Documents Directory which isn't actually where your folder is.
The Documents Directory is a folder on your actual device where you might save user data or other files which can be accessed at a latter date (for example via iTunes Sharing).
If you move your Models.scnassets folder under the yellow ArAds folder you should be able to access your content like so:
let myModelToLocate = SCNScene(named: "Models.scnassets/Phone_01.scn")
Hope it helps...
You've pointed me in a better direction, but I can already get the scn and make a node if I know the name. What I really want to do is populate a tableview with the options that are available - so I need to find the current list of scene files.
I think this will work:
let subdir = Bundle.main.resourceURL!.appendingPathComponent("Models.scnassets").path
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: subdir)
print(modelPathDirectoryFiles.count) //this works
//then do my thing with the array
} catch {
print("error getting list of files")
}
This seems to work, whether I move the folder or not.

iOS10 + Xcode8 documentDirectory weird behavior

It seems the documentDirectory in Xcode8/Swift3/iOS10, in a framework, on iOS seems unwritable.
API's used / tried:
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
( The last one does not seem to be preferred in Swift, which I can understand )
Now, whenever I try to write files to the URL returned in this area I do not seem to be capable of doing so ( both Simulator, and device ). Downloading the container or inspecting it does not show the files either ( I tried several methods of writing ). Also trying to create a directory to write into seems to fail.
The weird thing is that there is no error returned from within API's used or the FileManager itself.
Is there some horrible point I'm missing? Is it a bug I should report? Currently I moved to creating a directory in Library/ instead, as that seems to work and shouldn't be as volatile as Library/Cache/.
Code used to write ( realm.io was used before I decided to do this ):
let URLs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let data = Data.random(32) // Generates a 32 byte long random blob
try! data.write(to: URLs.last!) // Crashing here with a forced unwrap is fine
The path that you are writing to is invalid – you're passing in the directory path instead of the path to the file you want to create. You can craft a path like this:
let path = NSString(string: URLs.last!.path).appendingPathComponent("foo.txt")
Turns out you need to completely reset your Simulators and restart Xcode. Fun stuff.

Valid file path for archiverootobject and unarchiverootobject

I am making an iPhone app and in a previous question I was told that I needed a valid file path for archiverootobject and unarchiverootobject but I don't know how to make one. So what is a valid file path to save arrays of custom classes?
Follow up question: On the linked question I have set up my methods to use invalid saves but it still works would anyone know why?
You can save it to a subdirectory folder named with your bundleID inside the application support folder or you can also save it to the preferences folder located inside the library directory:
let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.plist")
print(fileURL.path) // "/var/folders/.../Library/Preferences/fileName.plist

Resources