Mike
Mike

Reputation: 237

Swift: Creating an NSXMLNode

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?

Upvotes: 2

Views: 449

Answers (1)

Martin R
Martin R

Reputation: 539745

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.

Upvotes: 4

Related Questions