sunshinejr / SwiftyUserDefaults

Modern Swift API for NSUserDefaults
http://radex.io/swift/nsuserdefaults/static
MIT License
4.85k stars 366 forks source link

Bool value not being correctly decoded when using launch arguments #159

Closed kierangraham closed 5 years ago

kierangraham commented 6 years ago

I'm using SwiftyUserDefaults in an app and running into an issue in a UI test when attempting to use a Bool value set from the launch arguments, I have a test as follows:

func testLocationTrackingSwitchDisabledState() {
    let app = XCUIApplication()
    app.launchArguments.append(contentsOf: ["-myBoolEnabled", "true"])
    app.launch()

   // ....
  }

When calling Defaults[.myBoolEnabled] I would expect to receive true ; instead it always returns false. I can confirm with Defaults.string(forKey: "myBoolEnabled") that a value is correctly present when passed in from the launch arguments, e.g.

po Defaults.string(forKey: "myBoolEnabled")
â–¿ Optional<String>
  - some : "true"

po Defaults.bool(forKey: "myBoolEnabled")
false

po Defaults[.myBoolEnabled]
false

I've noticed inside the source that there is a function with this comment:

    public static func get(key: String, userDefaults: UserDefaults) -> Bool? {
        // @warning we use number(forKey:) instead of bool(forKey:), because
        // bool(forKey:) will always return value, even if it's not set
        // and it does a little bit of magic under the hood as well
        // e.g. transforming strings like "YES" or "true" to true
        return userDefaults.number(forKey: key)?.boolValue
    }

Though I'm not able to find out where the magic under the hood is for handling "YES" or "true" values.

It may also be worth mentioning that launch arguments are explicitly String values for the key and value.

Thanks!


Version: 4.0.0-alpha.1

sunshinejr commented 6 years ago

Hey @kierangraham, please take a look at #148 (oh, I think adding the link to the discussion in the code would also help).

tl;dr there is an explanation of why it doesn't work, but I would like to add this functionality to SwiftyUserDefaults somehow anyways. Do not have a proper solution right now, though. But I'm open for ideas 😉

sunshinejr commented 5 years ago

Hey @kierangraham. I know it's a little bit late, but I'm adding the support for boolean values read from launch arguments in #180, so I thought that you may be interested in this. We've figured out a way of adding the functionality without making false-positives that bool(for:) does.

kierangraham commented 5 years ago

@sunshinejr Thanks for notifying me about this, I wish I'd have found the time to look at it but life tends to throw many distractions ;) – anyways, I've read your changes #180 and must say I really like the implementation you went with, great work and many thanks for thinking to tell me! 😄