Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storing nil in String? results in "" #162

Closed
mvoelkl opened this issue Aug 1, 2018 · 9 comments · Fixed by #171
Closed

Storing nil in String? results in "" #162

mvoelkl opened this issue Aug 1, 2018 · 9 comments · Fixed by #171

Comments

@mvoelkl
Copy link

mvoelkl commented Aug 1, 2018

This is my definition, please note the Optional type:

extension DefaultsKeys {
    static let myValue = DefaultsKey<String?>("myValue")
}

And this is how I'm storing my value:

Defaults[.myValue] = newValue

And this is me talking to llvm:

(lldb) po newValue
nil

(lldb) po Defaults[.myValue]
▿ Optional<String>
  - some : ""

Expected result: Defaults[.myValue] is nil
Version: 4.0.0-alpha.1
Installed via CocoaPods

@rromanchuk
Copy link

can confirm this happening, this is quite a dangerous bug

Below the branch always evaluates as true

Defaults[.authToken] = nil
if let authToken = Defaults[.authToken] {

}

@quangpc-zz
Copy link

quangpc-zz commented Sep 16, 2018

I can see this issue too
Version: 4.0.0-alpha.1

@farzadshbfn
Copy link

It's not a bug, you didn't define the .authToken correctly.
DefaultsKeys are default value provider and in String and String? case, it's "".
You can define your key like this:

extension DefaultsKeys {
	static let authToken = DefaultsKey<String?>("authToken", defaultValue: nil)
}

@rromanchuk
Copy link

rromanchuk commented Sep 24, 2018

@farzadshbfn no, it is a bug, trust me.

static let authToken = DefaultsKey<String?>("authToken", defaultValue: nil)

this returns ""

@farzadshbfn
Copy link

Well that's weird, because I "just" checked it before posting it 🤔

@quangpc-vn
Copy link

what version u used for testing @farzadshbfn . We use 4.0.0-alpha.1

@farzadshbfn
Copy link

farzadshbfn commented Sep 29, 2018

4.0.0-alpha.1, that's why I'm shocked!
although I should mention, I'm not using default Defaults value, I used UserDefaults with custom suiteName.

@z3bi
Copy link
Contributor

z3bi commented Oct 10, 2018

I experienced the same issue and manually specifying the defaultValue of nil did fix it. But digging into it I'm not sure why that's the case.

Without specifying the defaultValue, the convenience init should be calling the private init which sets the defaultValue to nil

    private init(key: String) {
        self._key = key
        self.defaultValue = nil
    }

so functionally both inits should be equivalent.

Further, the subscript function uses the nil coalescing operator to run through possible return values

return T.get(key: key._key, userDefaults: self) ?? key.defaultValue ?? T.defaultValue

the T.defaultValue is the blank string defined in the String extension

extension String: DefaultsSerializable, DefaultsDefaultArrayValueType, DefaultsDefaultValueType {

    public static var defaultValue: String = ""

So I'm not sure why the nil coalescing would ever return the specified nil defaultValue instead of the empty string.

@sunshinejr
Copy link
Owner

Hey guys. Indeed this is a bug. The problem came from the new "default values" protocols. We'll be removing them in a new alpha. Sorry for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants