0

enter image description here

func resetUserDefaults() {
    let userDefaults = UserDefaults.standard
    let dict = userDefaults.dictionaryRepresentation()

    for (key,_) in dict {
        if let key = key as? String {
            userDefaults.removeObject(forKey: key)
        } else {
            #if DEBUG
                NSLog("\(key)")
            #endif
        }
    }
}

I'm getting this warning. can anyone suggest me how to avoid this warnoing

rmaddy
  • 314,917
  • 42
  • 532
  • 579
iOSDude
  • 274
  • 2
  • 25
  • Just remove as? String from that line. – Krishnarjun Banoth Sep 04 '17 at 05:52
  • 1
    Dictionary keys are non-optional and all keys in `UserDefaults` must be strings by definition, they can never be `nil`. Remove the entire `if let` expression. – vadian Sep 04 '17 at 05:55
  • 1
    @vadian It's not that the key is optional, it's that `key` is already known to be a `String`. – rmaddy Sep 04 '17 at 05:57
  • @rmaddy I just added the point. – vadian Sep 04 '17 at 05:58
  • By the way, why not simply `UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)` – vadian Sep 04 '17 at 06:06
  • 1
    By the way, deleting values for **all** keys is not a good idea as they 1. might come from from Apple or 3rd party frameworks or 2. might not be contained in the user domain (i.e. the `globalDomain` or a shared suite). A better solution is to use `resetStandardUserDefaults()` – Nikolai Ruhe Sep 04 '17 at 06:47

5 Answers5

3

All keys in UserDefaults must be of type String. So key is declared as a String. So attempting to cast it to a String is pointless. Hence the warning.

All you need is:

func resetUserDefaults() {
    let userDefaults = UserDefaults.standard
    let dict = userDefaults.dictionaryRepresentation()

    for (key,_) in dict {
        userDefaults.removeObject(forKey: key)
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 2
    OK, what child is down voting all of the answers for no reason? Grow up. – rmaddy Sep 04 '17 at 06:05
  • @MIOSY I just noticed that you have not accepted an answer to any of your questions. For each of your questions, look at the answers. If you believe one of the answers best answered your question, please click the checkmark next to that answer. This lets people know your question have been solved. – rmaddy Sep 04 '17 at 14:14
1

There is no need to cast something to the type that it is already known (to the compiler) to have.

Just remove the whole condition and use your key directly.

Thilo
  • 257,207
  • 101
  • 511
  • 656
1

Since the keys in the UserDefault should of type String, casting the key to string is of no use, and hence you are getting this warning.

func resetUserDefaults() {
    let userDefaults = UserDefaults.standard
    let dict = userDefaults.dictionaryRepresentation()

    for (key, _) in dict {
       userDefaults.removeObject(forKey: key)
    }
}
skynet
  • 706
  • 4
  • 8
0

It will always show waring because dictionaryRepresentation() return [String : Any].

So when you cast from string to string it will definitely show warning. for more see this -> https://developer.apple.com/documentation/foundation/userdefaults/1415919-dictionaryrepresentation

Surjeet Rajput
  • 1,251
  • 17
  • 24
0

I had the same issue with a private function in Swift 5 and I found a solution working for me.

The solution was to change the value to optional. I added a question mark after the type I was looking for. (as String"?")

You can see an example here :

private func doSomeThing(completion: @escaping (String) -> ()) {
    let Something = somethingElse;
        if let anoterThing = something as String?{
        completion(anoterThing)
    }else{
        completion("Error at private func doSomeThing")
    }
}

You can find more pieces of information here:

https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html

Swift: difference as String? vs. as? String

Downcasting in Swift with as and as?

Best Regards