Search code examples
swiftnsfilemanager

Can someone explain what URLResourceKeys are?


I was looking at the documentation for contentsOfDirectory(at:includingPropertiesForKeys:options:)

Particularly I've been focusing on the argument includingPropertiesForKeys, which said:

An array of keys that identify the file properties that you want pre-fetched for each item in the directory. For each returned URL, the specified properties are fetched and cached in the NSURL object. For a list of keys you can specify, see Common File System Resource Keys.

Clicking on URLResourceKey led me to the Apple Documentation about it.

And I was wondering, if I passed in keys like fileResourceTypeKey, fileResourceIdentifierKey, and creationDateKey how could I access those in the returned URL list (after calling contentsOfDirectory(at:includingPropertiesForKeys:options:))?

And I was also confused by the URLResourceKey enum b/c a lot of types have similar descriptions and names to other keys like:

  • documentIdentifierKey vs fileResourceIdentifierKeyvs localizedNameKey vs nameKey
  • localizedTypeDescriptionKey vs fileResourceTypeKey vs typeIdentifierKey
  • the urls returned by the contentsOfDirectory(at:includingPropertiesForKeys:options:) vs pathKey

Like what would be the differences between these keys?

Basically I have a really low understanding of the file system at this point so please bear with my "simple" questions. If someone could explain what all these keys means and how I can access/use them that would be great!


Solution

  • First of all the URLResourceKey documentation describes the kind of the attribute information very well. For example nameKey returns always Desktop for an URL representing ~/Desktop while localizedNameKey returns the localized name Schreibtisch on a German system or Bureau on a French system. However documentIdentifierKey and fileResourceIdentifierKey are completely different attributes.


    Regarding the contentsOfDirectory(at:includingPropertiesForKeys:options:) API: The keys passed in the includingPropertiesForKeys parameter tells the framework to pre-fetch the corresponding attributes while getting the contents for performance reasons. For example

    let contentURLs = try fileManager.contentsOfDirectory(at: anURL, includingPropertiesForKeys: [.nameKey, .fileSizeKey], options: .skipsHiddenFiles)
    

    To read the attributes call resourceValues(forKeys on the URL passing the same keys as in contentsOfDirectory. Then get the value with the corresponding property of the resource key. The benefit of the combination URLResourceKey / URLResourceValues is you get always the proper type from the file attributes. This avoids any type casting.

    for fileURL in contentURLs {
         do {
            let fileAttributes = try fileURL.resourceValues(forKeys:[.nameKey, .fileSizeKey])
            print(fileAttributes.name!) // is String
            print(fileAttributes.fileSize!) // is Int
         } catch { print(error, fileURL) }
    }