Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot force unwrap value of non-optional type: Avoid "Optional()"

Tags:

xcode

swift

I've saved player skills in NSUserDefaults as a dictionary but when I want to access it, xcode says "cannot force unwrap value of non-optional type". When I remove "!" it writes out "Optional (1)" where I want to get rid of "Optional()". How can I just write out "1"?

if let playerDic = defaults.objectForKey("Player") as? [String: Int] {
    lbLevel.setText(String(playerDic!["level"]))
}

turns into

"Cannot force unwrap value of non-optional type"

where

if let playerDic = defaults.objectForKey("Player") as? [String: Int] {
    lbLevel.setText(String(playerDic["level"]))
}

turns into

Optional(1)
like image 622
NicklasF Avatar asked Nov 18 '15 16:11

NicklasF


People also ask

How do you unwrap optional binding?

An if statement is the most common way to unwrap optionals through optional binding. We can do this by using the let keyword immediately after the if keyword, and following that with the name of the constant to which we want to assign the wrapped value extracted from the optional.

What is unwrapped in Swift?

Unwrapping in Swift is essentially verifying if the Optional value is nil or not, and then it performs a task only if it's not nil. You can perform unwrapping in the following ways: Using an if else block. Using Forced unwrapping. Using Optional binding.


2 Answers

You've already unwrapped playerDic in the if let binding. Just drop the force unwrap like the error message tells you.

if let playerDic = defaults.objectForKey("Player") as? [String: Int] {
    lbLevel.setText(String(playerDic["level"]))
}

Update Sorry just saw your update. So playerDic isn't an optional, but the values returned for keys are optionals. If you ask for the value for a key that is not in the dictionary you will get an optional with the value of nil.

if let 
      playerDic = defaults.objectForKey("Player") as? [String: Int],
      level = playerDic["level"]   {
    lbLevel.setText("\(level)")
}

Here you can bind multiple values in a single if let. Also, you can use String(level) or use string interpolation "(level)" depending on what you prefer.

like image 188
Mr Beardsley Avatar answered Sep 30 '22 15:09

Mr Beardsley


The bang at the end (!) :

You are trying to pass an optional to a method that does not receive nil: String(optional) to solve this just unwrap it with (!) at the end String(optional!):

if let playerDic = defaults.objectForKey("Player") as? [String: Int] {
    lbLevel.setText(String(playerDic["level"]!)) <-- the bang at the end
}
like image 38
Pedro Trujillo Avatar answered Sep 30 '22 15:09

Pedro Trujillo