Unexpectedly found nil while unwrapping an Optional valueについて


swiftでコードを書いています。

swiftのシミュレーター でiphone8でビルドしても普通に動くんですが、それ以外の実機(iphoneX)などでビルドするとUnexpectedly
found nil while unwrapping an Optional valueというエラーが出ます。

ちなみにエラーの箇所は  
let userDefaults: UserDefaults = UserDefaults.standard  
let teamID: String = (userDefaults.object(forKey: "teamID")! as? String)!  
です。

userDefaultsの箇所なのですが、新しい実機でビルドすると値を取得できないとかあるのですか？

わかる方教えてください。




**_userDefaultsの箇所なのですが、新しい実機でビルドすると値を取得できないとかあるのですか？_**

`UserDefaults`はあなたのアプリが初めてインストールされた直後は空っぽです。これは実機でもシミュレータでも変わりません。

「シミュレーター
でiphone8でビルドしても普通に動く」と言うことですが、開発中からiPhone8のシミュレータを何度か使用していたので、過去に値を設定するコードが動いていたのでしょう。試しに今まであなたのアプリを一度も試したことのないシミュレータがあれば、どうなるかやってみると良いでしょう。

と言うわけで、`UserDefaults`にアクセスする場合は、最初は空の可能性があると言うことを常に意識しておかないといけません。

と言うか、表題の **Unexpectedly found nil while unwrapping an Optional value**
に関連して言うと、あなたのコードは危険な「私のアプリをクラッシュさせて演算子」(`!`)を使いすぎですね。Conditional
Bindingや`??`演算子などをうまく使用して、`nil`耐性のあるコードにすることをお勧めします。

さらについでに言うと、設定値が`String`型であることがわかっている場合には、`string(forKey:)`メソッドを使われた方がいいでしょう。

[code]

        let userDefaults = UserDefaults.standard
        if let teamID = userDefaults.string(forKey: "teamID") {
            //teamIDを使う
            print("teamID:", teamID)
            //...
        } else {
            //teamIDに初期値を入れる
            print("teamID is nil, setting default value")
            userDefaults.set("...", forKey: "teamID")
            //...
        }
    
[/code]

teamIDがどんな使い方をされるのかによって、色々なやり方はあるでしょうが、もしセキュリティ上外部から見られてはいけない情報なら`UserDefaults`(や普通のファイルやCore
Data等)ではなく、Keychainの使用を検討された方がいいと思います。

