Understanding Unexpected found nil while unwrapping an Optional value

Asked 2 years ago, Updated 2 years ago, 46 views

I am writing the code with swift.

It works normally when I build it with iphone8 in the swift simulator, but when I build it with other real machines (iphoneX), I get the Unexpected found nil while unwrapping an Optional value error.

By the way, the error part is
br/> let userDefaults: UserDefaults=UserDefaults.standard
Let teamID: String=(userDefaults.object(forKey: "teamID")!as?String)!
That's it.

As for the userDefaults part, is there any possibility that I can't get the value when I build it with a new actual machine?

Please let me know if you understand.

swift

2022-09-30 21:34

2 Answers

Regarding userDefaults, is there a possibility that I cannot get the value when I build it with a new actual machine?

UserDefaults is empty right after your app is first installed.This is the same for real machines and simulators.

It says, "Even if you build it with iPhone8 in a simulator, it works normally." But since I used the iPhone8 simulator several times during development, I guess the code for setting the value was working in the past.If you have a simulator that has never tried your app before, try it out.

Therefore, when accessing UserDefaults, you must always be aware that it can be empty at first.

Or, in relation to the title Unexpected found nil while unwrapping an optional value, your code uses a dangerous ! operator.We recommend that you use the nil operator well to make the code resistant.

Furthermore, if you know that the setting is of type String, you may want to use the string(forKey:) method.

let userDefaults=UserDefaults.standard
    iflet teamID=userDefaults.string(forKey: "teamID") {
        // Use teamID
        print("teamID:", teamID)
        //...
    } else{
        // Enter initial value for teamID
        print("teamID is nil, setting default value")
        userDefaults.set("...", forKey: "teamID")
        //...
    }

Depending on how teamID is used, there may be many ways to do this, but if it is information that should not be viewed by the outside world for security reasons, you should consider using Keychain instead of UserDefaults.


2022-09-30 21:34

UserDefaults means you can't retrieve the value unless you set the value yourself. Do you set the value of the key in Userdefaults.standard.register([String:Any]) before calling object(forKey:) at application startup?
Or do you set the value in userDefaults.set("[Team ID]", forKey:"teamID")?

If not,
In ! right after userDefaults.object(forKey:"teamID"), I think nil will be unwrapped and dropped.

So the easiest solution is
let teamID: String=(userDefaults.object(forKey: "teamID")???"[Default value when teamID was nil]" as? String)!
However, UserDefault is more like a place to save application settings, and I think the team ID shown in the example should be stored in an external file or a database file such as CoreData, SQLite, etc.

Therefore, to create a program where userDefaults.object(forKey:"teamID") does not become nil,

Create a defaults.plist in the project and list all the values of the keys referenced there (in this case, teamID).

at application startup (for example, applicationDidFinishLaunching).
do{
    let bundle —Bundle=Bundle.main
    iflet defaultsURL:URL=bundle.url(forResource: "defaults", withExtension: "plist") {
        let defaults —Dictionary<String, Any>=try NSDictionary (contentsOf:defaultsURL)
        UserDefaults.main.registerDefaults(defaults)
    } // end found defaults.plist
} catch{
    print("defaults.plist is not found")
}

As the , you must register the values to be referenced in the future programs.


2022-09-30 21:34

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.