Alchemy
Alchemy

Reputation: 3

SKSpriteNode name to int

I'm trying to convert an SKSpriteNode item name to an Int...

That's the code:

let item = SKSpriteNode(imageNamed: "enemy")
item.name = "1"

Then, in touchesEnded:

guard let touch = touches.first else { return }
let location = touch.location(in: self)
let touchedSKSpriteNode = self.atPoint(location)

processItemTouched(node: touchedSKSpriteNode as! SKSpriteNode)

The func processItemTouched tries to extract the name of the touched element and converts it to an Int:

func processItemTouched(node: SKSpriteNode) {
    let num: Int =  Int(node.name)  // Error
}

But there is an error: "Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?"

After clicking on Fix-it, it becomes:

let num: Int =  Int(node.name)!   // Error, again

But another error appears: "Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?"

Finally, it's working, after fixing:

let num: Int =  Int(node.name!)!

It works but there's a problem: if I try to verify if num != nil, Xcode says that "Comparing non-optional value of type 'Int' to nil always returns true".

Is there a way to avoid this alert?

Upvotes: 0

Views: 181

Answers (2)

Jean-Baptiste Yunès
Jean-Baptiste Yunès

Reputation: 36391

You are using Int type construtor Int?(String) which means it needs a String and returns an optional Int (Int?).

node.name is an optional property of SKNode, because nodes can have no name. So you have been suggested to force dereferencing (but this is very dangerous). You can provide a default value as node.name ?? <default> or use the if-let:

if let name = node.name {
   // do something with name in the case it exists!
}

Then you tried to store the Int? produced in a variable of type Int, and the IDE suggested you to force dereferencing it (again a bad thing). Again you can provide a default value let i : Int = Int(node.name ?? "0") ?? 0 or use the if-let pattern:

if let name = node.name, let i = Int(name) {
   // do want you want with i and name...
} else {
   // something bad happened
}

Upvotes: 0

glyvox
glyvox

Reputation: 58029

This is a tricky situation, since both the name of the node and the result of the conversation can be nil.

I'd suggest providing a default value for the name using ??, forcefully unwrapping the optional with ! is very inelegant and dangerous (if a node does not have a name and you try to use this function with it, your app will crash).

You should either:

  • declare num as an optional (either explicitly or by leaving out the type altogether):

    let num = Int(node.name ?? "") //Int?
    
  • provide a default value for num:

    let num = Int(node.name ?? "") ?? 0 //Int
    

Learn more about optionals here.

Upvotes: 1

Related Questions