2

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?

Mike
  • 227
  • 2
  • 5

1 Answers1

4

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382