XMLDocument.xmlData(withOptions:) won't compile

Hi all, please help!


Swift 3, this builds:

let xdat: NSData = xDoc.xmlData as NSData

This does not:

let xdat: NSData = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint)) as NSData

My error is:

/Proj/.../ConfigManager.swift:55:35: error: cannot call value of non-function type 'Data'
        let xdat: NSData = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint)) as NSData
                           ~~~~~~~~~~~~^


Of course one is a property and the other is a method. Both return type Data:

https://developer.apple.com/reference/foundation/xmldocument#1770347


Anyone have any ideas why I can't get ".xmlData(withOptions:)" to compile? Calling just ".xmlData" builds & runs fine, but generates XML packed onto one line. The XML I write absolutely has to be human-readable/editable!


Thanks for any assistance,


Tadd

Answered by OOPer in 184580022

Try this:

let xdat: NSData = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint.rawValue)) as NSData


`XMLNode.Options.nodePrettyPrint` is an enum, which cannot be converted to Int with initializer. You need to convert its rawValue (:UInt) to Int.

And when you have any number of type related errors as such, Swift does not generate a good diagnostics for methods overloaded with properties.


By the way, why don't you make your `xdat` as `Data`? As Swift 3 imports almost all `NSData` in the Cocoa APIs as `Data`, you can work better with them, using `Data` as far as you can.

let xdat: Data = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint.rawValue))
Accepted Answer

Try this:

let xdat: NSData = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint.rawValue)) as NSData


`XMLNode.Options.nodePrettyPrint` is an enum, which cannot be converted to Int with initializer. You need to convert its rawValue (:UInt) to Int.

And when you have any number of type related errors as such, Swift does not generate a good diagnostics for methods overloaded with properties.


By the way, why don't you make your `xdat` as `Data`? As Swift 3 imports almost all `NSData` in the Cocoa APIs as `Data`, you can work better with them, using `Data` as far as you can.

let xdat: Data = xDoc.xmlData(withOptions: Int(XMLNode.Options.nodePrettyPrint.rawValue))

Try this:


let xdat: NSData = xDoc.xmlData(withOptions: Int (XMLNode.Options.nodePrettyPrint.rawValue)) as NSData


You need to use ".rawValue" because XMLNode.Options is an OptionsSet and the xmlData method requires numeric options. You need "Int(…)" around it because the raw value is a UInt rather than an Int.


You should file a bug report about this API. Either it should have translated (from the Obj-C header in the SDK) to a method that uses XMLNode.Options directly, or (if for some reason the "withOptions" parameter must be numeric) XMLNode.Options shouldn't be translated to an OptionsSet.

Great advice guys and thanks for the extremely speedy help! Of course it builds now & works splendidly. I wish I could mark you both as "correct answer" but alas.


I'm having a hard time adapting to these .Options in Swift and, as you alluded to OOPer, moving from the NS APIs to the non-NS ones. I guess old habits die hard. As you suggested, I did change my code to use Data [and e.g. xdat.write(to: URL(fileURLWithPath: pathXmlFile), options: NSData.WritingOptions.atomic) etc.] and everything looks so much cleaner. Thanks!


QuincyMorris: I'll figure out how to file a bug report as you suggested (even if it exposes me as a noob!) because, while I'm really starting to think that Swift is a beautiful language, something so fundamental as enum handling, in its current incarnation, seems a kludgey blemish! It shouldn't be that way; it'll turn prospective devs off. Xcode's contextual help doesn't help much and whatever online help hasn't made my own transition much easier.


Thanks again guys,

Tadd

Can you elaborate on why you think the enum handling is, in itself, kludgey? (The Swift compiler team does read these forums from time to time, so expressing an opinion here can have an indirect effect on the language, to some degree.) In your particular case, it was a combination of (a) enum, plus (b) OptionsSet, plus (c) badly translated API that caused the difficulty. Of those, #c seems to be something like a bug, and #b is kindof a workaround to bridge between Obj-C and Swift universes. It's a standard mechanism, now, across a lot of Cocoa APIs, so it's a pattern to learn rather than something obvious. But Swift enums in isolation are rather good, I think, which is why I'm interested to hear a different opinion.


Don't worry about how a bug report makes you look. It's a genuine fault in Swift if it forces you to write 4 kinds of guff to get a simple result. You're allowed an opinion just like everyone else.

Good evening Quincey and thanks for the nice words...


My criticism might not be very precise. You summed it up well, however... especially when you refer to a badly translated API, which resonated with me. I've only been doing Swift for 2 months now (although coming from decades in other languages), but please bear with me as I fumble through a foggy recollection of my Swift "options" experience.


First of all, the contextual pop-up help (which other IDEs may call "intellisense" and accomplish quite effectively, especially when dealing with a new/huge/changing API/language) in Xcode often feels very unhelpful! I hope Apple improves it soon.


My issue with Options for myriad API calls is that they seem like an inconsistent mixture of simple enums (which for instance cannot be OR'ed together) versus occasional enums expected to be used as bit values (hence bitwise-OR'ed) versus, and this really confused me: something like JSONSerialization.jsonObject(with:options:) where the last parameter seems to be expected as an array. ...which for defaults, must be passed as []... while some options lists can be passed as nil, others cannot.


I'm probably continuing my sloppiness in those descriptions, but that's where I'm at right now. I feel like it's going into my spinning head as a jumbled mess! Surely this will improve as I learn the language more and everything settles down. And hopefully, like you said, Apple can continue work on this.

In the meantime I'll keep fumbling along, but I will try to keep up here more. Thanks again for your thoughts.


Tadd

XMLDocument.xmlData(withOptions:) won't compile
 
 
Q