質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%

Q&A

解決済

1回答

959閲覧

do catch文の使い方

siitake

総合スコア2

0グッド

1クリップ

投稿2021/06/07 04:47

前提・実現したいこと

swiftUI で数字が入力されたらシートを表示して
数字以外が入力されたらアラートを表示するアプリを作成しています。
TextField に入力された文字列が Double に変換できるか do catch文でチェックすることで
数字かそうでないかを判断しようと考えています。
その do catch文でエラーメッセージが発生してしまいました。

発生している問題・エラーメッセージ

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

該当のソースコード

ContentView.swift

import SwiftUI struct ContentView: View { @State var bun:String! = "" @State private var showingAlert = false @State private var showingSheet = false var body: some View { VStack{ //Bindingにoptional変数をアンラップして渡すには「text: Binding($bun)!」(強制アンラップ) TextField("入力", text: Binding($bun)!, onCommit:{ a() }) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() Text(bun) .alert(isPresented: $showingAlert){ Alert(title: Text("title"), message: Text("message"),dismissButton: .default(Text("push"))) } .sheet(isPresented: $showingSheet){ Image(systemName:"hand.thumbsup.fill") } } } func a() { do{ let s:Double! = try Double(bun)! //ここにエラーメッセージが発生 self.showingSheet = true } catch{ self.showingAlert = true } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

try はエラーが発生する場合に使いますが、文字列を数値に変換する Double(_:) の戻り値はオプショナルで、エラーは発生しないので、try は使えません。数値に変換できない場合は nil が返るので、結果が nil かどうかで判定しましょう。また、変数 s は使わないなら _ にすると警告がなくなります。
参考: Swift 4.0 エラー処理入門 - Qiita
参考: Swiftの _ (アンダースコア) - Qiita

swift

1 func a() { 2 if let _ = Double(bun) { // または if Double(bun) != nil { 3 self.showingSheet = true 4 } else { 5 self.showingAlert = true 6 } 7 }

元のコードでは try Double(bun)! としてますが、! による強制アンラップは失敗した場合、try の対象になるエラーではなく、プログラム自体が強制終了してしまうことになりますので、なるべく使わない方が良いでしょう。(UIKit では使わざるをえない場合もありますが、SwiftUI なら基本的に使う必要はないはず。)
参考: Swift nil 強制アンラップをしない! - Qiita
参考: Swiftのエラーハンドリングはなぜ最先端なのか - Qiita

それと、@State var bun の型を String! にする必要はありませんし、! を取り除けば TextField の text: には $bun をそのまま渡せるようになります。

diff

1 struct ContentView: View { 2- @State var bun:String! = "" 3+ @State var bun = "" 4 @State private var showingAlert = false 5 @State private var showingSheet = false 6 7 var body: some View { 8 VStack{ 9- //Bindingにoptional変数をアンラップして渡すには「text: Binding($bun)!」(強制アンラップ) 10- TextField("入力", text: Binding($bun)!, onCommit:{ 11+ TextField("入力", text: $bun, onCommit:{ 12 // 以下略

投稿2021/06/07 07:28

hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問