Swift Optional Dictionary [String: String?] unwrapping error
Asked Answered
B

2

0

So here I have a basic setup

var preferenceSpecification = [String : String?]()
preferenceSpecification["Key"] = "Some Key"
preferenceSpecification["Some Key"] = nil
preferenceSpecification["DefaultValue"] = "Some DefaultValue"
print(preferenceSpecification)
var defaultsToRegister = [String : String]()

if let key = preferenceSpecification["Key"], let defaultValueKey = preferenceSpecification["DefaultValue"] {
    defaultsToRegister[key] = preferenceSpecification[defaultValueKey]!
}

But the error points out where it demands that I force unwrap this, to be like this:

defaultsToRegister[key!] = preferenceSpecification[defaultValueKey!]!

Which doesn't make sense, because keyValue and defaultValue already are unwrapped

Banderilla answered 18/8, 2016 at 19:39 Comment(5)
Possible duplicate of Optional Type Dictionary yields "Value of Optional type not unwrapped"Smell
keyValue is nowhere defined in your code.Spumescent
@Martin R corrected, sorryBanderilla
Compare #27225732: preferenceSpecification["..."] is a String? because that is the value type of [String : String?](). Do you really want the value to be optional? What should happen if preferenceSpecification["Key"] is defined as nil in the dictionary?Spumescent
It's expected a different action, that node is ignored. but as @Smell pointed out, and the question you marked closes the case. There's no need to mark [String: String?], the value is optional by default.Banderilla
L
2

When you extract a value from a dictionary like this using subscript

[String: String?]

you need to manage 2 levels of optional. The first one because the subscript returns an optional. The second one because the value of you dictionary is an optional String.

So when you write

if let value = preferenceSpecification["someKey"] {

}

you get value defined as an optional String.

Here's the code to fix that

if let
    optionalKey = preferenceSpecification["Key"],
    key = optionalKey,
    optionalDefaultValueKey = preferenceSpecification["DefaultValue"],
    defaultValueKey = optionalDefaultValueKey,
    value = preferenceSpecification[defaultValueKey] {
    defaultsToRegister[key] = value
}

Suggestions

  1. You should avoid force unwrapping as much as possible. Instead you managed to put 3 ! on a single line!
  2. You should also try to use better name for your constants and variables.
Leavis answered 18/8, 2016 at 19:58 Comment(1)
It was just a test case to place it on the StackOverflow, the code on the project is way more complex. But as it was pointed out, the value of an object on dictionary may be nil, it's by default an optional. A little deeper: developer.apple.com/swift/blog/?id=12Banderilla
R
1

You could also define an extension which helps get rid of the double optional situation.

extension Dictionary where Value == Optional<String> {
    
    func flattened(_ key: Key) -> Value {
        if let value = self[key] {
            return value
        }
        return nil
    }
        
}

Usage: preferenceSpecification.flattened("someKey")

Rifkin answered 5/8, 2020 at 11:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.