iOS:无法将文件保存到“应用程序支持”文件夹,但可以将“文档”
我可以使用自定义名称下载并保存二进制文件到“文档”文件夹中。
如果我只是将URL更改为“应用程序支持”文件夹,而不是“文档”文件夹,则无法写入该URL,表示该URL不存在。
以下是url构build代码:
- ( NSURL * ) getSaveFolder { NSURL * appSupportDir = nil; NSURL * appDirectory = nil; NSArray * possibleURLs = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSAllDomainsMask]; if ( [possibleURLs count] >= 1 ) { appSupportDir = [possibleURLs objectAtIndex:0]; } if ( appSupportDir != nil) { NSString * appBundleID = [[NSBundle mainBundle] bundleIdentifier]; appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID]; } return appSupportDir; }
这是保存代码:
- ( void ) writeOutDataToFile:( NSData * )data { NSURL * finalURL = [self.rootPathURL URLByAppendingPathComponent:self.aFileName]; [data writeToURL:finalURL atomically:YES]; }
如果我将NSArray更改为:
NSArray * possibleURLs = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
那么它可以保存好。
我已经阅读了关于文件的Apple Docs文件,无法解决这个问题 – 我错过了什么?
与Documents
目录不同,默认情况下Application Support
目录不存在于应用程序的沙箱中。 您需要先创build它,然后才能使用它。
而一个更简单的方法来获得对该目录的引用是:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); NSString *appSupportDirectory = paths.firstObject;
如果有人不确定如何做rmaddy描述:
NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; //If there isn't an App Support Directory yet ... if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir isDirectory:NULL]) { NSError *error = nil; //Create one if (![[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:&error]) { NSLog(@"%@", error.localizedDescription); } else { // *** OPTIONAL *** Mark the directory as excluded from iCloud backups NSURL *url = [NSURL fileURLWithPath:appSupportDir]; if (![url setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:&error]) { NSLog(@"Error excluding %@ from backup %@", url.lastPathComponent, error.localizedDescription); } else { NSLog(@"Yay"); } } }
我遇到了同样的问题,并决定使用更简洁的方法:
let fileManager = NSFileManager.defaultManager() let urls = fileManager.URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask) as! [NSURL] if let applicationSupportURL = urls.last { fileManager.createDirectoryAtURL(applicationSupportURL, withIntermediateDirectories: true, attributes: nil, error: nil) }
这是withIntermediateDirectories: true
因为createDirectoryAtURL
使用withIntermediateDirectories: true
只会在文件夹不存在的withIntermediateDirectories: true
下创build。
下面是iOS的一些Swift代码,可以将二进制数据文件写入应用程序支持目录。 这部分是由chrysAllwood的答案启发。
/// Method to write a file containing binary data to the "application support" directory. /// /// - Parameters: /// - fileName: Name of the file to be written. /// - dataBytes: File contents as a byte array. /// - optionalSubfolder: Subfolder to contain the file, in addition to the bundle ID subfolder. /// If this is omitted no extra subfolder is created/used. /// - iCloudBackupForFolder: Specify false to opt out from iCloud backup for whole folder or /// subfolder. This is only relevant if this method call results in /// creation of the folder or subfolder, otherwise it is ignored. /// - Returns: Nil if all OK, otherwise text for a couple of non-Error errors. /// - Throws: Various errors possible, probably of type NSError. public func writeBytesToApplicationSupportFile(_ fileName : String, _ dataBytes : [UInt8], optionalSubfolder : String? = nil, iCloudBackupForFolder : Bool = true) throws -> String? { let fileManager = FileManager.default // Get iOS directory for "application support" files let appSupportDirectory = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first if appSupportDirectory == nil { return "Unable to determine iOS application support directory for this app." } // Add "bundle ID" as subfolder. This is recommended by Apple, although it is probably not // necessary. if Bundle.main.bundleIdentifier == nil { return "Unable to determine bundle ID for the app." } var mySupportDirectory = appSupportDirectory!.appendingPathComponent(Bundle.main.bundleIdentifier!) // Add an additional subfolder if that option was specified if optionalSubfolder != nil { mySupportDirectory = appSupportDirectory!.appendingPathComponent(optionalSubfolder!) } // Create the folder and subfolder(s) as needed if !fileManager.fileExists(atPath: mySupportDirectory.path) { try fileManager.createDirectory(atPath: mySupportDirectory.path, withIntermediateDirectories: true, attributes: nil) // Opt out from iCloud backup for this subfolder if requested if !iCloudBackupForFolder { var resourceValues : URLResourceValues = URLResourceValues() resourceValues.isExcludedFromBackup = true try mySupportDirectory.setResourceValues(resourceValues) } } // Create the file if necessary let mySupportFile = mySupportDirectory.appendingPathComponent(fileName) if !fileManager.fileExists(atPath: mySupportFile.path) { if !fileManager.createFile(atPath: mySupportFile.path, contents: nil, attributes: nil) { return "File creation failed." } } // Write the file (finally) let fileHandle = try FileHandle(forWritingTo: mySupportFile) fileHandle.write(NSData(bytes: UnsafePointer(dataBytes), length: dataBytes.count) as Data) fileHandle.closeFile() return nil }