UIDocument.fileAttributesToWrite signature changed in Xcode 10/Swift 4.2

My apologies if there is a separate forum for Xcode 10, but I didn't see it.


I have the following code for a UIDocument subclass to generate a thumbail image for the UIDocumentBrowswerViewController to dispay.


    public override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [AnyHashable : Any] {

        let slide = self.slideAtIndex(0)!
        let image = slide.image(self.imageSize, document: self)

        return [
            URLResourceKey.hasHiddenExtensionKey: true,
            URLResourceKey.thumbnailDictionaryKey: [
                URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: image
            ]
        ]
    }

Xcode10/Swift 4.2 has changed the signature to:


publicoverridefunc fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [FileAttributeKey : Any]

It does not compile because the return dictionary key types do not match. There does not seem to be a FileAttributeKey for saving a thumbnail. Is this an oversight or is there a way around this? For now I've filed rdar://40808963


Thanks,

Dave

Accepted Reply

The answer of Claud31 is very suggesting, but you may need something like this:

return [
   FileAttributeKey(URLResourceKey.hasHiddenExtensionKey.rawValue): true,
   FileAttributeKey(URLResourceKey.thumbnailDictionaryKey.rawValue): [
       URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: image
    ]
]

The outermost keys for the returned dictionary need to be of type `FileAttributeKey`.

The type `FileAttributeKey` is a thin wrapper for `NSString` and you can initialize it with a String value.

Replies

Here are all the thumbnail keys :


Thumbnail Keys


static let thumbnailKey: URLResourceKey

All thumbnails as a single NSImage (read-write).


static let thumbnailDictionaryKey: URLResourceKey

A dictionary of NSImage/UIImage objects keyed by size (read-write).

See URLThumbnailDictionaryItem for a list of possible keys.

static let NSThumbnail1024x1024SizeKey: URLThumbnailDictionaryItem


struct URLThumbnailDictionaryItem

Possible keys for the thumbnailDictionaryKey dictionary.


So, the key exists.


Did you try to covert to FileAttributeKey

FileAttributeKey(URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey.rawValue)


URLResourceKey.thumbnailDictionaryKey: [
                FileAttributeKey(URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey.rawValue): image
            ]


Direct cast as FileAttributeKey does not work.

The answer of Claud31 is very suggesting, but you may need something like this:

return [
   FileAttributeKey(URLResourceKey.hasHiddenExtensionKey.rawValue): true,
   FileAttributeKey(URLResourceKey.thumbnailDictionaryKey.rawValue): [
       URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: image
    ]
]

The outermost keys for the returned dictionary need to be of type `FileAttributeKey`.

The type `FileAttributeKey` is a thin wrapper for `NSString` and you can initialize it with a String value.

Thanks for the responses and sorry for the delay (I didn't get an email notification that anyone had replied even though the forum shows me following this topic). Claud31's is not enough but OOPer's reply does allow it to compile. I haven't tried it on a device yet as I'm waiting for beta 2 before updating my iPad.

I am wondering if this ever worked. I have not been able to get a custom thumbnail to appear for the documents. I cannot seem to determine that the fileAttributesToWrite code is even being executed.


I have tried two versions based on the notes here.


override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [AnyHashable : Any] {
let thumbnail = self.thumbnail


return [
URLResourceKey.hasHiddenExtensionKey: true,
URLResourceKey.thumbnailDictionaryKey: [
URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: thumbnail

]

]


}



override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [AnyHashable : Any] {
let thumbnail = self.thumbnail
return [
FileAttributeKey(URLResourceKey.hasHiddenExtensionKey.rawValue): true,
FileAttributeKey(URLResourceKey.thumbnailDictionaryKey.rawValue): [
URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: thumbnail
]
]



}



I am using XCODE 10.2.1 and Swift 5.


Thanks

As far as I tried in Xcode 10.2.1 with iOS Simulator 12.2, this code worked as expected:

    override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [AnyHashable : Any] {
        let image: UIImage? = UIImage(named: "icon@1024x1024.png")
        return [
            URLResourceKey.hasHiddenExtensionKey: true,
            URLResourceKey.thumbnailDictionaryKey: [
                URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: image
            ]
        ]
    }

This code as well:

    override func fileAttributesToWrite(to url: URL, for saveOperation: UIDocument.SaveOperation) throws -> [AnyHashable : Any] {
        let image: UIImage? = UIImage(named: "icon@1024x1024.png")
        return [
            FileAttributeKey(URLResourceKey.hasHiddenExtensionKey.rawValue): true,
            FileAttributeKey(URLResourceKey.thumbnailDictionaryKey.rawValue): [
                URLThumbnailDictionaryItem.NSThumbnail1024x1024SizeKey: image
            ]
        ]
    }

If both of your code did not work, there is something wrong in the hidden parts of your code. Better start a new thread for your own issue.