Swift: Creating an NSXMLNode

442 Views Asked by At

I'm trying to create an NSXMLNode using Swift. This seems like it should be pretty straightforward based on the class reference (and Xcode's autocompletion):

var anAttribute: NSXMLNode = NSXMLNode.attributeWithName("name", stringValue: "string")

But I get an error: "Missing argument for parameter 'URI' in call."

I then try:

var anAttribute: NSXMLNode = NSXMLNode.attributeWithName("name", URI: "uri", stringValue: "string")

Which produces the equally beguiling error: "Extra argument 'URI' in call."

Can anyone tell me what's going on here?

1

There are 1 best solutions below

0
Martin R On BEST ANSWER

attributeWithName() returns AnyObject?, the Swift mapping of id. Therefore you have to cast the return value to the expected type:

let anAttribute = NSXMLNode.attributeWithName("name", stringValue: "string") as NSXMLNode

or, if you want to check for a possible failure:

if let anAttribute = NSXMLNode.attributeWithName("name", stringValue: "string") as? NSXMLNode {
    // success
} else {
    // failed
}

The underlying reason is that the Objective-C function

+ (id)attributeWithName:(NSString *)name stringValue:(NSString *)value

returns id. If it were declared as

+ (instancetype)attributeWithName:(NSString *)name stringValue:(NSString *)value

(which is the "modern" way to declare class/factory methods) then this would be mapped to Swift as

 class func attributeWithName(_ name: String!,
             stringValue value: String!) -> NSXMLNode!

making the explicit cast unnecessary. You could file a bug report to Apple about that.