Data to different types ?

Is there documentation for converting Data to any specific Type ?


I'm trying to get & set Date Last Opened and came across a nice extension someone posted for getting & settings Extra Attributes ... https://stackoverflow.com/questions/38343186/write-extend-file-attributes-swift-example it's the first response. Found the attribute "com.apple.lastuseddate#PS" which comes back as Data. I tried searching Google but again didn't find much, just examples of turning Data into Strings. Would be nice to have a single document for any type ?


I have no idea if this relates to the same thing but at the moment am using "NSMetadataItem(url: url)?.value(forAttribute: NSMetadataItemLastUsedDateKey) as? Date" which works fine although not sure about setting the attribute.

Post not yet marked as solved Up vote post of Pendragon Down vote post of Pendragon
3.5k views

Replies

Found this which has been a little helpful but still no Date https://stackoverflow.com/questions/43241845/how-can-i-convert-data-into-types-like-doubles-ints-and-strings-in-swift

When you want to convert `Data` to some specific type, you need to know the data format of the Data.

When it is not a primitive type as in the linked article, things are not so easy.


And about the data format stored in extended attributes, there are very little information on the web.

Seems Apple would not like app programmers to access extended attributes explicitly, and they may be differ in versions of macOS.

As of "com.apple.lastuseddate#PS", I can get 16-byte Data, such as:

                    let lastUseddDateData = try url.extendedAttribute(forName: "com.apple.lastuseddate#PS")
                    print(lastUseddDateData as NSData)

-> <0430cb5c 00000000 4805492c 00000000>

It seems to be two 64-bit integers (little endian). I guess the first represents something like Unix time in seconds, and the other sub-seconds.


As far as I tested, the first seems to represent seconds from 1970-01-01 00:00:00 (UTC) (as well as Unix time), and the other for subseconds in nano-second.

                    let (seconds, subseconds) = lastUseddDateData.withUnsafeBytes {bytes in
                        return (bytes.load(as: Int64.self),
                                bytes.load(fromByteOffset: 8, as: Int64.self))
                    }
                    let NANO_SECONDS_IN_SECOND: TimeInterval = 1_000_000_000
                    let lastUsedData = Date(timeIntervalSince1970: TimeInterval(seconds)+TimeInterval(subseconds)/NANO_SECONDS_IN_SECOND)
                    print(lastUsedData, lastUsedData.timeIntervalSinceReferenceDate)

-> 2019-05-02 17:59:32 +0000 578512772.7429831

The result is nearly equivalent to the Date given by `NSMetadataItem(url: url)!.value(forAttribute: NSMetadataItemLastUsedDateKey) as! Date`, seems you have no need to access this extended attribute directly.


                    let date = NSMetadataItem(url: url)!.value(forAttribute: NSMetadataItemLastUsedDateKey) as! Date
                    print(date, date.timeIntervalSinceReferenceDate)

-> 2019-05-02 17:59:32 +0000 578512772.742983

OOPer wrote:

Seems Apple would not like app programmers to access extended attributes explicitly …

You should not depending on the name and format of extended attributes unless they are explicitly documented. So, it’s OK to do general things with extended attributes, like copy them, but you need to avoid poking around inside them unless they have a documented format. This is not the case here.

In most cases, these extended attributes act as the backing store for higher-level APIs, and that’s what you should be using. In this specific case, you should use

NSMetadataItemLastUsedDateKey
.

I guess the first represents something like Unix time in seconds, and the other sub-seconds.

FYI, this is a UNIX

timespec
structure (not to be confused with the UNIX
timeval
structure, which uses microseconds for its second element), although that fact does not change my advice above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks. I couldn't find anything and am assuming I can't write Spotlight data to a file, which is why I was looking at accessing the extra attributes. Any idea saving the date ?