Swift MoveItem fails due to file "does not exist" - ios

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)

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).

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?

Using an iPhone or iPad, how can I access a folder created by FileManager.default.createDirectory(...)?

I've created an iOS app that creates a "Photos" folder using FileManager, like this:
let appPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let photosPath = appPath.appendingPathComponent("Photos", isDirectory: true)
try FileManager.default.createDirectory(at: photosPath, withIntermediateDirectories: true, attributes: nil)
I know I can access that directory in the simulator by using Finder and going to:
Users/xxxx/Library/Developer/Devices/[my device GUID]/data/Containers/Data/Application/[my app GUID]/Documents/Photos
But how can I access that folder using the real device itself? (iPad or iPhone)
The native browser doesn't show my app directory

Sqlite File Location between ionic app and native app

I'm trying to reach the sqlite database from an app made with ionic.
when making the app with ionic, the database is stored in this directory:
/Users/sistemas/Library/Developer/CoreSimulator/Devices/{alfanumeric}/data/Containers/Data/Application/{alfanumeric}/Library/LocalDatabase/test.db
But when i run the app made in xcode (8.2), the file is generated in another directory:
/Users/sistemas/Library/Developer/CoreSimulator/Devices/{alfanumeric}/data/Containers/Data/Application/{alfanumeric}/Documents/test.db
I have both database files in the xcode-made app and don't know how to reach the first test.db. Has anybody the solution to it?
Just changed a little mi original method for calling the database..
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("test.db")
To:
let fileURL = try! FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("LocalDatabase/test.db")
You can set the enum "FileManager.SearchPathDirectory" of the app from .documentDirectory to .libraryDirectory and just appended "LocalDatabase/".

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!

Resources