Extended file attribute (xattrs) accessor ยต-Framework for Swift

What's New

Initial working release


Basic functionality and a working API draft.


Swift 3 Version License Platform Carthage compatible

Micro-Framework to offer a way more convenient way to read and write extended file attributes (xattrs) on files in Swift.


For maximum convenience, define regular used extended attributes as extensions to Xattrs.Attributes:

extension Xattrs.Attributes {
    static var authorName: Xattr<String> { return Xattr(name: "authorName") }

Then use the Xattrs subscript accessors to read and write values:

// Type annotations added to clarify the API
let url: URL = // ... 
let xattrs = Xattrs(url: url)

let originalAuthor: String? = xattrs[.authorName]

let plagiarizer = "Karl-Theodor zu Guttenberg"
xattrs[.authorName] = plagiarizer
print(xattrs[.authorName]) // "Karl-Theodor zu Guttenberg" 

You do not need to keep the lightweight Xattrs object around if you quickly need to change or read a value:

Xattrs(url: url)[.authorName] = "John Doe"

Less Convenient Example

The Xattrs subscript will return optional values instead of emitting errors. If you need more control, you can have it!

The underlying accessors are defined as extensions to URL:

  • URL.extendedAttribute(forName:) throws -> Data
  • URL.setExtendedAttribute(data:forName:) throws
  • URL.removeExtendedAttribute(forName:) throws
let url: URL = // ...

do {
    let data = try url.extendedAttribute(forName: "com.apple.TextEncoding")
    // decode data etc.
} catch {

Extending Xattrs to support more types

The Xattrs type defines a general-purpose subscript as a wrapper for the aforementioned URL extension:

  • Xattrs.subscript(xattrKey: String) -> Data?

You can use this as the basis for serializing and deserializing your own types.

Xattrs also comes with wrappers for NSKeyedArchiver's object-based encoding and decoding. It's super simple to utilize that part of the API for arbirtrary objects:

extension Xattrs {
    public subscript(xattr: Xattr<Banana>) -> Banana? {
        get { return decode(xattrKey: xattr.name) }
        set { storeEncoded(xattrKey: xattr.name, value: newValue) }

Until Swift supports generic subscripts like subscript<T>(xattr: Xattr<T>) -> T?, we have to define all supported types using extensions.


The base of all this are the extensions on URL, written by Martin R in an answer on StackOverflow.

Code License

Copyright (c) 2017 Christian Tietze. Distributed under the MIT License.


  • Swift Tools
View More Packages from this Author


  • None
Last updated: Sun Dec 25 2022 23:06:20 GMT-0500 (GMT-05:00)