iOS9 Filemanager File Permissions Change

iOS9 FileManager File permissions change

The original code is just wrong. You need to use the octal representation of the permissions:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-literal

Correct code:

let fileManager = NSFileManager.defaultManager()

let directory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let path = "\(directory)/file.txt"

let attributes: [String:AnyObject] = [NSFilePosixPermissions: NSNumber(short: 0o666)]
let success = fileManager.createFileAtPath(path, contents: nil, attributes: attributes)
if success && fileManager.isWritableFileAtPath(path) && fileManager.isReadableFileAtPath(path) {
NSLog("Worked!")
} else {
NSLog("Failed!")
}

A function I used to test all possible permissions.

func testPermissions() {
let types: [Int16] = [0o666, 0o664, 0o662, 0o660, 0o646, 0o626, 0o606, 0o466, 0o266, 0o066]
for t in types {
testCreateFile(t)
}
}

func testCreateFile(permissions: Int16) {
let attributes: [String:AnyObject] = [NSFilePosixPermissions: NSNumber(short: permissions)]

let directory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let filename = "filename\(permissions.description)"
let path = "\(directory)/\(filename)"

let fileManager = NSFileManager.defaultManager()
let success = fileManager.createFileAtPath(path, contents: nil, attributes: attributes)

if success && fileManager.isWritableFileAtPath(path) && fileManager.isReadableFileAtPath(path) {
let octal = String(format:"%o", permissions)
NSLog("It worked for \(octal)")
}
}

iOS9 Swift File Creating NSFileManager.createDirectoryAtPath with NSURL

I figured this one out. createDirectoryAtPath() is unable to process a path with the "file://" prefix. To get a path without the prefix you must use path() or relativePath().

let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let logsPath = documentsPath.URLByAppendingPathComponent("logs")
do {
try NSFileManager.defaultManager().createDirectoryAtPath(logsPath.path!, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}

Incorrect path (notice file://):

file:///var/mobile/Containers/Data/Application/F2EF2D4F-94AF-4BF2-AF9E-D0ECBC8637E7/Documents/logs/

Correct path:

/var/mobile/Containers/Data/Application/F2EF2D4F-94AF-4BF2-AF9E-D0ECBC8637E7/Documents/logs/

Permission Denied when trying to create a directory in Application Support

The problem is in this line

directory = URL(fileURLWithPath: directory).appendingPathComponent("IAP").absoluteString

This return filePath, while below function required simple path of directory.

fileManager.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)

So either change this line

directory = URL(fileURLWithPath: directory).appendingPathComponent("IAP").absoluteString

with this line

directory = directory + "/IAP"

OR
change same line with below line

let url = URL(fileURLWithPath: directory).appendingPathComponent("IAP")

and use this function to create directory

fileManager.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)

Hope this helps you.

Error: You don’t have permission to save the file in the folder

Thanks to this post I realized its because of this line:

let destString = destPath.absoluteString

I had to change it to:

let destString = documentsURL.relativePath

Which allowed me to greatly simplify my function:

static func unzipFile(atPath path: String) -> Bool
{
let destString = documentsURL.relativePath

let success: Void? = try? SSZipArchive.unzipFile(atPath: path, toDestination: documentsURL.relativePath, overwrite: true, password: nil)

if success == nil
{
return false
}

return true
}

Different path URL for FileManager everytime I open the app

You are using the wrong API. absoluteString (in rootURL.absoluteString) returns the string representation including the scheme file://. The correct API for file system URLs is path

I recommend to use the URL related API as much as possible

public func directoryExists(at url: URL) -> Bool {
let fileManager = FileManager.default
var isDir : ObjCBool = false
if fileManager.fileExists(atPath: url.path, isDirectory:&isDir) {
return isDir.boolValue
} else {
return false
}
}

and compose the URL in a more reliable way

func createARObjectDirectory() {
let rootURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if directoryExists(at: rootURL.appendingPathComponent(DefaultURL.arObjectUrlDirectoryName) {
Logger.logServer("ARObject directly found")
} else {
createNewDirectory(name: DefaultURL.arObjectUrlDirectoryName)
}
}

And this is swiftier too

public func createNewDirectory(name: String) {

let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let dirURL = documentDirectory.appendingPathComponent(name)
do
{
try FileManager.default.createDirectory(at: dirURL, withIntermediateDirectories: false, attributes: nil)
}
catch let error as NSError
{
Logger.logError("Unable to create directory \(error.debugDescription)")
}
Logger.logInfo("Dir Path = \(dirPath.path)")
}



Related Topics



Leave a reply



Submit