BAD_ACCESS exception trying to get the Documents folder URL - ios

I have weird issue with core data and iOS9 (9.3). This call throws BAD_ACCESS on iOS9:
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
It works nice on iOS 10, but crashes on iOS 9.
I was digging more and found that even if I call this, app crashes:
print(FileManager.SearchPathDirectory.documentDirectory)
What am I missing? Some config somewhere? I tried it on completely new project and on both device/emulator. I temporarily solved it by bridging it from Objective-C, but that is not right solution.

Try this
let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]

So problem was here:
https://github.com/apple/swift/pull/5055
Waiting for new xcode.

Related

Can't find file in Filemanager

I have a file on my iPhone that I can see in the Files app. However when I look for it in Filemanager with swift I can't find it. I'm in the documents directory and it's not there. I updated the plist for UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace.That didn't help. Anyone know how to get the files that are in the Files App.
Code for documents:
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
Thanks in Advance.
You are sandboxed. You cannot programmatically navigate to where this file is. You have to get the user to navigate to it for you (in, for example, a UIDocumentPickerViewController).

Swift MoveItem fails due to file "does not exist"

So I'm trying to rename a folder within my app, but the moveItem method is behaving strangely. Here is my code:
try FileManager.default.moveItem(at: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("parentFolder").appendingPathComponent("folderIWantToMove"), to: FileManager.default.urls(for: .applicationDirectory, in: .userDomainMask)[0].appendingPathComponent("parentFolder").appendingPathComponent("newFolderName"))
This fails and the message in the debugger is:
“folderIWantToMove” couldn’t be moved to “parentFolder” because either the former doesn’t exist, or the folder containing the latter doesn’t exist.
But when I run this in the lldb:
print FileManager.default.fileExists(atPath: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("parentFolder").appendingPathComponent("folderIWantToMove").path)
and
print FileManager.default.fileExists(atPath: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("parentFolder").path)
both return true, meaning both folders do exist. I've read some other questions with similar problems and most of them say that it is because of sandboxing. If this is the case how could I be able to change the name of and erase files within the user's document directory?
Just in case, I'm using swift 5 and running everything on an iPad with iPadOS 13 from Xcode 12 beta.
The issue there is that you are not renaming it, you are trying to move your directory from inside your documents directory to the application directory which is out of your bundle and unreachable from your app in iOS.
let document = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let parentFolder = document.appendingPathComponent("parentFolder")
let folderIWantToMove = parentFolder.appendingPathComponent("folderIWantToMove")
do {
try FileManager.default.createDirectory(at: folderIWantToMove, withIntermediateDirectories: true, attributes: nil)
print("folder and sub folder created")
print("folderIWantToMove path:", folderIWantToMove.path)
// renaming it
let newFolderName = parentFolder.appendingPathComponent("newFolderName")
try FileManager.default.moveItem(at: folderIWantToMove, to: newFolderName)
print("folder renamed to:", newFolderName.path)
} catch {
print(error)
}
I've had the same file problem, but on macOS. I fixed it by adding the "com.apple.security.files.user-selected.read-write" entitlement and setting it as true. I hope this helps! (Also, make sure to set the app sandbox entitlement to false)

Loading document in shared documents folder into WKWebView

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!

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.

NSFileManager fileExistsAtPath in Swift 2.0?

So, using Swift 2.0, it looks like Apple are steering us towards using NSURL rather than NSString for paths.
I’m trying to ascertain whether a file exists in the user’s Documents directory in iOS, and I can’t quite piece it together.
If I use the following, Swift 2.0 complains that I shouldn’t use stringByAppendingPathComponent, and that I should use URLs.
let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let dbPath = documents.stringByAppendingPathComponent(“Whatever.sqlite”)
If I then get the URL, like so:
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileURL = documentsURL.URLByAppendingPathComponent("Retrollect.sqlite”)
I then can’t call NSFileManager.defaultManager().fileExistsAtPath to ascertain whether the file exists.
Is there an equivalent of fileExistsAtPath() for an NSURL, to look inside the user’s Documents directory?
Never mind, one of those "five seconds later" answers.
I can use fileExistsAtPath(theURL.path) to do this. Checking that the path is non-nil first, of course!
Swift 4 version:
FileManager.default.fileExists(atPath: url.path)

Resources