Hi I have an app which uses its own document format (.hvgg). The UTI is declared in the Info.plist (screenshot). Did I do anything wrong there? Because when I use the "Share" menu, it shows "Copy to HvGG" instead of "Import to HvGG" which it says with all the other apps.
Anyways, my actual problem is that I can't find the file that is imported. I tried to find it using the document directory and adding "Inbox" but that didn't work. Is there a new path where the files are saved?
This is my code:
var opened: String?
var path: String?
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if String(describing: url)[0..<4] == "file" {
opened = "stundenplan"
let filemanager = FileManager.default
let paths: NSArray = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
let documentsDirectory: String = paths.object(at: 0) as! String
path = documentsDirectory.appending("/Inbox")
let dirFiles = try! filemanager.contentsOfDirectory(atPath: path!) <-- throws error
print (dirFiles)
}
return true
}
The error it returns:
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=260 "The folder “Inbox” doesn’t exist." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/9C0586AF-C0B8-440A-9151-13C6A061B3FB/Documents/Inbox, NSUserStringVariant=(
Folder), NSUnderlyingError=0x174050e90 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.31.3/src/swift/stdlib/public/core/ErrorType.swift, line 182
Related
I am trying to get the FileAttributesKey using FileManager in iOS using Swift. When I try that, I am getting the following error"
Error Domain=NSCocoaErrorDomain Code=260 "The file “Personal%20Narrative%20Essay.txt” couldn’t be opened because there is no such file." UserInfo={NSFilePath=file:///private/var/mobile/Library/Mobile%20Documents/com~apple~TextEdit/Documents/Personal%20Narrative%20Essay.txt, NSUnderlyingError=0x283e720a0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
It says that the file doesn't exist but I know that it does exist because it is appearing in the UIDocumentPicker and I am able to get the contents of the file using try! Data(contentsOf: URL).
My code for getting the attributes of the file is:
func processURL(url: URL) -> Bool {
let newPath = url.absoluteString
print(newPath)
do {
let attributes = try FileManager.default.attributesOfItem(atPath: newPath)
let fileSize = attributes[FileAttributeKey.size]
print("Calculated File Size: \(fileSize!)")
return true
}
catch {
print(error)
self.isShowingSpinner = false
self.isShowingURLErrorAlert = true
return false
}
return true
}
I just need to be able to get the file size for now which I am doing using the above function. I do not understand if I am doing something wrong. Thanks in advance for the help.
I could reproduce your issue with a simple Playground where I placed a resource called "hello.text".
Here are the results:
let filePath = Bundle.main.path(forResource: "hello", ofType: "txt")!
// Prints as /var/folders/blah-blah-blah/hello.txt
let fileURL = Bundle.main.url(forResource: "hello", withExtension: "txt")!
// Prints as file:///var/folders/blah-blah-blah/hello.txt
The issue is that the file:// prefix is specific to file's URL and is not expected for path arguments of type String.
try FileManager.default.attributesOfItem(atPath: fileURL.absoluteString) // ❌
try FileManager.default.attributesOfItem(atPath: fileURL.path) // ✅
I'm making a game on iPad (v10.2.1) with Xcode(version 8.2.1) and while I'm trying to save some data in documents folder in the sandbox, I found that all ways I tried failed: createDirectory and createFile(using file manager), and writeToUrl(using NSData). I ran the program on 2 iPads and 1 iPhone and no success.
I was able to read from a plist I created, and convert it to a dictionary, using the function convertDataFrom().
I'm new to data persistence or file manipulation and my game stuck here. would appreciate any help!
func loadData()->NSDictionary{
let fm = FileManager()
let sourceUrl = Bundle.main.url(forResource: "Data", withExtension: "plist")!
var appSupportDir = fm.urls(for: .documentDirectory, in: .userDomainMask).first! as? NSURL
appSupportDir = appSupportDir!.appendingPathComponent("UserData", isDirectory: true) as NSURL?
let urlForSave = (appSupportDir!.appendingPathComponent("Data.plist"))!
//load data, or if file doesn't exist yet, create one
var isDirectory: ObjCBool = false
if fm.fileExists(atPath: urlForSave.absoluteString, isDirectory: &isDirectory) {
let data = convertDataFrom(url: urlForSave)
print("data file exists")
print(isDirectory)
return data as NSDictionary
} else {
do { try fm.createDirectory(atPath: appSupportDir!.absoluteString!, withIntermediateDirectories: true, attributes: nil) }catch let Error {
print("create directory failed")
print(Error)
}
let originalData = NSData.init(contentsOf: sourceUrl)
print("\(urlForSave)")
do { try originalData?.write(toFile: urlForSave.absoluteString, options: .atomic) } catch let Error {
print(Error)
}
if (!fm.createFile(atPath: urlForSave.absoluteString, contents: originalData as Data?, attributes: nil)) {
fatalError("file creation failed")
}
let data = convertDataFrom(url: urlForSave)
print("\(data)")
print(isDirectory)
return data as NSDictionary
}
}
func convertDataFrom(url: URL)->Dictionary<String, Any> {
let dictionary = NSDictionary.init(contentsOf: url) as! Dictionary<String, Any>
return dictionary
}
Error messages for "createDirectory": Error Domain=NSCocoaErrorDomain
Code=513 "You don’t have permission to save the file “UserData” in the
folder “Documents”."
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/,
NSUnderlyingError=0x174053f50 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}}
file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/Data.plist
and for "createFile" (fatalError if createFile fails) Error
Domain=NSCocoaErrorDomain Code=4 "The file “Data.plist” doesn’t
exist."
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/Data.plist,
NSUnderlyingError=0x174055bd0 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}} fatal error: file creation failed: file
/Users/chanwu/Desktop/Math_DownStairs/Math_DownStairs/
Your code checks to see if urlForSave (the final file) exists, and if it doesn't, you then try to create the UserData directory.
If the final file doesn't exist, but the UserData directory does, I would expect the exact outcome you describe.
You should probably change your test to see if the UserData directory exists instead of testing for the final file. That way if the directory doesn't exist you'll create it, and then call write(toFile:), which will create the file if it doesn't exist.
After transferring a file from iPhone to Apple Watch I get the Error
Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"
What do I do wrong? These are the code snippets:
iPhone ViewController
func makeAction () {
let url = NSURL.fileURL(withPath: fileArray[0].object(at: 2) as! String)
var applicationDict = Dictionary<String, Array<AnyObject>>()
applicationDict["fileArray"] = fileArray
WCSession.default().transferFile(url, metadata: applicationDict)
}
Watch InterfaceController
func session(_ session: WCSession, didReceive file: WCSessionFile) {
DispatchQueue.main.async(execute: { () -> Void in
print("RECEIVED")
var applicationDict = Dictionary<String, Array<AnyObject>>()
applicationDict = file.metadata as! Dictionary<String, Array<AnyObject>>
self.fileArray = applicationDict["fileArray"]!
self.fileList = self.fileArray
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let tempDocsDir = dirPaths[0] as String
let docsDir = tempDocsDir.appending("/")
let filemgr = FileManager.default
do {
let fileName = self.fileArray[0].object(at: 1) as! String
try filemgr.moveItem(atPath: file.fileURL.path, toPath: docsDir + fileName)
} catch let error as NSError {
print("Error moving file: \(error.description)")
}
self.loadTableData()
})
}
Full Error Message
Error moving file: Error Domain=NSCocoaErrorDomain Code=4
"“5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3” couldn’t be moved to “Documents” because either the former doesn't
exist, or the folder containing the latter doesn't exist."
UserInfo={NSSourceFilePathErrorKey=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/Inbox/com.apple.watchconnectivity/FCE7E6CB-2452-4E0A-9AFF-F5B3A51A0DE8/Files/0B96CCB0-A2E1-418B-9859-97C22238A5F5/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSUserStringVariant=(
Move ), NSFilePath=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/Inbox/com.apple.watchconnectivity/FCE7E6CB-2452-4E0A-9AFF-F5B3A51A0DE8/Files/0B96CCB0-A2E1-418B-9859-97C22238A5F5/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSDestinationFilePath=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSUnderlyingError=0x7b776110 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}}
The documentation for didReceiveFile notes:
File: The object containing the URL of the file and any additional information. If you want to keep the file referenced by this parameter, you must move it synchronously to a new location during your implementation of this method. If you do not move the file, the system deletes it after this method returns.
So make sure to not async in this method before moving the file to a location your app has access to.
Alright, got it. putting this in an async dispatch was wrong. Without ist -> work perfectly. Please go ahead, nothing to see here :)
I have an incoming PDF attachment coming into my app. It's coming in as NSURL assigned in the AppDelegate:
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
The file prints to the print log as:
Incoming File:
file:///private/var/mobile/Containers/Data/Application/65E4F19F-98DD-4A4E-8A49-E1C564D135D8/Documents/Inbox/Burrito.pdf
How can I get the file out of the DocumentDirectory Inbox folder where it is put by default for an incoming file? I tried to create a new folder called "Recipes" and then move it to this folder, but it won't I get the error:
Unable to create directory Error Domain=NSCocoaErrorDomain Code=516
"“Burrito-2.pdf” couldn’t be moved to “Documents” because an item with
the same name already exists."
UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/D5C9B472-B880-4D68-BA0D-31BA545E2150/Documents/Inbox/Burrito.pdf,
NSUserStringVariant=(
Move ), NSDestinationFilePath=/var/mobile/Containers/Data/Application/D5C9B472-B880-4D68-BA0D-31BA545E2150/Documents/Recipes,
NSFilePath=/private/var/mobile/Containers/Data/Application/D5C9B472-B880-4D68-BA0D-31BA545E2150/Documents/Inbox/Burrito.pdf,
NSUnderlyingError=0x13912e0e0 {Error Domain=NSPOSIXErrorDomain Code=17
"File exists"}}
My code to move the file is:
// Incoming file
print("Incoming File: \(incomingFileTransfer)")
// File Manager
let filemgr = NSFileManager.defaultManager()
// Document Directory
var dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
// Documents Location
let docsDir = dirPaths[0] //as! String
print("Documents Folder: \(docsDir)")
print("------------------------")
// Create a new folder in the directory named "Recipes"
print("Creating new folder...")
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let newPath = documentsPath.URLByAppendingPathComponent("Recipes")
do {
try NSFileManager.defaultManager().createDirectoryAtPath(newPath.path!, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
print("New Path: \(newPath)")
print("------------------------")
// Moving item in folder
print("Moving PDf file to new folder...")
let startingPath = incomingFileTransfer
let endingPath = newPath
do {
try filemgr.moveItemAtURL(startingPath, toURL: endingPath)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
I'm new to Swift and have been research online and documentation on file management, but can't figure this out. I looked here but it is different and also in Objective-C; converting to Swift is hard for me. I'm using Xcode7 and Swift2, Thank you.
You get the errors when you run the application the second time and the directory is already created and the file has already been moved.
Apple highly recommends to use the URL related API of NSFileManager
First get the documents directory
// File Manager
let filemgr = NSFileManager.defaultManager()
// Document Directory
let docsDirURL = try! filemgr.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
The try! statement is safe because the documents directory always exists.
Then check if the Recipes directory exists. If not, create it
let recipesURL = docsDirURL.URLByAppendingPathComponent("Recipes")
if !filemgr.fileExistsAtPath(recipesURL.path!) {
do {
try filemgr.createDirectoryAtURL(recipesURL, withIntermediateDirectories: false, attributes: nil)
print("Directory created at: \(recipesURL)")
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
return
}
}
You can also check if the destination file exists
let incomingFileName = incomingFileTransfer.lastPathComponent!
let startingURL = incomingFileTransfer
let endingURL = recipesURL.URLByAppendingPathComponent(incomingFileName)
if !filemgr.fileExistsAtPath(endingURL.path!) {
do {
try filemgr.moveItemAtURL(startingURL, toURL: endingURL)
} catch let error as NSError {
NSLog("Unable to move file \(error.debugDescription)")
}
}
i am creating a directory so that i can save temp videos onto it as TempVideos is a folder now my video clips will be inside the folder...
func createTempDirectoryToStoreVideos(){
var error: NSError?
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
tempVideoPath = documentsDirectory.stringByAppendingPathComponent("TempVideos")
if (!NSFileManager.defaultManager().fileExistsAtPath(tempVideoPath!)) {
NSFileManager.defaultManager() .createDirectoryAtPath(tempVideoPath!, withIntermediateDirectories: false, attributes: nil, error: &error)
}
}
Now in these directory i want to store the videos as
func saveCompressVideoToTempDirectory(var compressedVideoUrl:NSURL?){
let data = NSData(contentsOfURL: compressedVideoUrl!)
var error:NSError?
var success = data?.writeToFile(tempVideoPath!, options: NSDataWritingOptions.AtomicWrite, error: &error)
println(error)
if let temp = success{
if temp {
println("success")
}else{
println("not valid ")
}
}
}
Howver i get error as
Optional(Error Domain=NSCocoaErrorDomain Code=512 "The operation
couldn’t be completed. (Cocoa error 512.)" UserInfo=0x17407f6c0
{NSFilePath=/var/mobile/Containers/Data/Application/F1140A9F-8D16-444B-8679-9ED1AD3F5E6A/Documents/TempVideos,
NSUnderlyingError=0x17424a320 "The operation couldn’t be completed. Is
a directory"})
Could you try createFileAtPath for that?
func createFileAtPath(_ path: String,
contents data: NSData?,
attributes attr: [String : AnyObject]?) -> Bool
The same thing concerns writeToFile:
func writeToFile(_ path: String,
options writeOptionsMask: NSDataWritingOptions) throws
where, look out, path is
The location to which to write the receiver's bytes. If path contains
a tilde (~) character, you must expand it with
stringByExpandingTildeInPath before invoking this method.
You should write this:
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var dirpath: String = paths[0] as String
let filepath = dirpath.stringByAppendingPathComponent("myOwnData.mov")