Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa Swift, get/set hidden (visible/invisible) flag on files and directories

I want to test if a file or directory on the file system has a certain flag, in this case the 'hidden' flag and then set it or remove it. I know this is possible through the command line, but I was wondering if I could do it with Cocoa/Swift?

I tried using NSFileManager attributesOfItemAtPath, but the returned object does not contain the flags.

example:

let fm = NSFileManager.defaultManager()

do {
    let testLibrary = try fm.attributesOfItemAtPath(dataPath)
    print (testLibrary)
} catch let error as NSError {
    print("JSON Error: \(error.localizedDescription)")
}

returns:

["NSFileCreationDate": 2013-08-16 21:37:57 +0000,
 "NSFileGroupOwnerAccountName": staff, 
 "NSFileType": NSFileTypeDirectory, 
 "NSFileSystemNumber": 16777220, 
 "NSFileOwnerAccountName": xjx, 
 "NSFileReferenceCount": 61, 
 "NSFileModificationDate": 2015-10-22 07:25:12 +0000, 
 "NSFileExtensionHidden": 0, 
 "NSFileSize": 2074,
 "NSFileGroupOwnerAccountID": 20, 
 "NSFileOwnerAccountID": 501, 
 "NSFilePosixPermissions": 448, 
 "NSFileSystemFileNumber": 603923]

For comparison, when I do ls -lO in my home directory, I see the following (notice the hidden flag on 'Library'):

drwx------+ 49 xjx  staff  -        1666 Jan 11 19:43 Downloads
drwx------@ 28 xjx  staff  -         952 Jan 11 08:40 Dropbox
drwx------@ 61 xjx  staff  hidden   2074 Oct 22 09:25 Library
drwx------+  7 xjx  staff  -         238 Apr 30  2015 Movies
drwx------+  5 xjx  staff  -         170 Jun 14  2015 Music
like image 979
ngstschr Avatar asked Dec 02 '22 15:12

ngstschr


2 Answers

Xcode11 • Swift 5, Xcode 9 • Swift 4 or Xcode 8 • Swift 3

extension URL {
    /// `true` is hidden (invisible) or `false` is not hidden (visible)
    var isHidden: Bool {
        get {
            return (try? resourceValues(forKeys: [.isHiddenKey]))?.isHidden == true
        }
        set {
            var resourceValues = URLResourceValues()
            resourceValues.isHidden = newValue
            do {
                try setResourceValues(resourceValues)
            } catch {
                print("isHidden error:", error)
            }
        }
    }
}
like image 55
Leo Dabus Avatar answered May 23 '23 05:05

Leo Dabus


You can use the NSURL API for this; here's an example:

// Create an NSURL object
let url = NSURL(fileURLWithPath: "/path/to/some/file.txt")!

// Catching errors
var error: NSError?

// Setting isHidden
let isHidden = NSNumber(bool: true)
if !url.setResourceValue(isHidden, forKey: NSURLIsHiddenKey, error: &error) {
    println(error?.localizedDescription)
}

// Getting isHidden
var value: AnyObject?
if !url.getResourceValue(&value, forKey: NSURLIsHiddenKey, error: &error) {
   println(error?.localizedDescription)
} else {
    var boolAsString = (value as! NSNumber).boolValue ? "TRUE" : "FALSE"
    println("\(url.path!) is hidden: \(boolAsString)")
}

The key methods are setResourceValue(_:forKey:error:) and getResourceValue(_:forKey:error:). In each case the key parameter is one of the URL's resource properties - the NSURL class reference provides a list on the most common ones towards the bottom of the page.

like image 28
Paul Patterson Avatar answered May 23 '23 05:05

Paul Patterson