NSFileManager & NSFilePosixPermissions

2019-04-07 17:03发布

问题:

I want to use the octal permissions (used for chmod) for NSFilePosixPermissions. Here is what I did now:

NSFileManager *manager = [NSFileManager defaultManager];
NSDictionary *attributes;

[attributes setValue:[NSString stringWithFormat:@"%d", 0777] 
             forKey:@"NSFilePosixPermissions"]; // chmod permissions 777
[manager setAttributes:attributes ofItemAtPath:@"/Users/lucky/Desktop/script" error:nil];

I get no error, but when I check the result with "ls -o" the permission are't -rwxrwxrwx.

What's wrong? Thanks for help.

回答1:

First, NSFilePosixPermissions is the name of a constant. Its value may also be the same, but that’s not guaranteed. The value of the NSFilePosixPermissions constant could change between framework releases, e. g. from @"NSFilePosixPermissions" to @"posixPermisions". This would break your code. The right way is to use the constant as NSFilePosixPermissions, not @"NSFilePosixPermissions".

Also, the NSFilePosixPermissions reference says about NSFilePosixPermisions:

The corresponding value is an NSNumber object. Use the shortValue method to retrieve the integer value for the permissions.

The proper way to set POSIX permissions is:

// chmod permissions 777

// Swift
attributes[NSFilePosixPermissions] = 0o777

// Objective-C
[attributes setValue:[NSNumber numberWithShort:0777] 
             forKey:NSFilePosixPermissions];


回答2:

Solution in Swift 3

let fm = FileManager.default

var attributes = [FileAttributeKey : Any]()
attributes[.posixPermissions] = 0o777
do {
    try fm.setAttributes(attributes, ofItemAtPath: path.path)
}catch let error {
    print("Permissions error: ", error)
}


回答3:

Solution in Swift 4

I tried using 0o777 and this did not change the file to read-only. I believe the correct way of doing it is the following:

let fileManager = FileManager.default

let documentsUrl: URL = self.fileManager.urls(for: .documentDirectory, in: .userDomainMask).first as URL!

let destinationFileUrl = documentsUrl.appendingPathComponent(fileName)

let readOnlyAttribute: [FileAttributeKey: Any] = [
            .posixPermissions: 0777
        ]
do {       

    try fileManager.setAttributes(readOnlyAttribute, ofItemAtPath: destinationFileUrl.path)

    if fileManager.isWritableFile(atPath: destinationFileUrl.path) {
        print("writeable")
    } else {
        print("read only")
    }

} catch let error {

    print("Could not set attributes to file: \(error.localizedDescription)")
}