## Day 19 Challenge - Dealing with bad input

 Aug '20 Hi so my conversion app is working as intended (almost!) I would like to pop an alert when a valid Double is not provided as well as setting the default value to 0. I have almost achieved this but I believe I am changing my showingAlert variable to true in the wrong place. I get the warning: Modifying state during view update, this will cause undefined behaviour Can anyone help? ``````// // ContentView.swift // Converter // // Created by Lee Casey on 09/08/2020. // Copyright © 2020 Lee Casey. All rights reserved. // // C -> F = (0°C × 9/5) + 32 = 32°F // F -> C = (0°F − 32) × 5/9 // C -> K = 0°C + 273.15 = 273.15K import SwiftUI struct ContentView: View { @State private var source = "" @State private var sourceSelection = 0 @State private var resultSelection = 0 @State private var showingAlert = false let units = ["Celcius", "Farenheit", "Kelvins"] //work all calculations from C func calcBase() -> Double { //let x = Double(source) ?? 0.0 var x: Double if let unwrapped = Double(source) { x = unwrapped } else { x = 0.0 showingAlert = true } if (sourceSelection == 1) { return (x - 32) * 5/9 } else if (sourceSelection == 2) { return x - 273.15 } return x } func calculate() -> Double { if (resultSelection == 0) { return Double(calcBase()) } else if (resultSelection == 1) { return (Double(calcBase()) * 9/5) + 32 } else { return (Double(calcBase()) + 273.15) } } var body: some View { NavigationView { Form { Section(header: Text("Please enter the amount you want to convert")) { TextField("Enter here", text: \$source) .keyboardType(.decimalPad) Picker("Unit", selection: \$sourceSelection) { ForEach(0 ..< units.count) { Text("\(self.units[\$0])") } } .pickerStyle(SegmentedPickerStyle()) .alert(isPresented: \$showingAlert) { Alert(title: Text("ERROR"), message: Text("Please enter a valid number"), dismissButton: .default(Text("OK"))) } } Section(header: Text("Results")) { Text("\(calculate(), specifier: "%.2f")") Picker("Unit", selection: \$resultSelection) { ForEach(0 ..< units.count) { Text("\(self.units[\$0])") } } .pickerStyle(SegmentedPickerStyle()) } } .navigationBarTitle("Converter") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } `````` 3 Aug '20 Your call to calculate() changes the value of showingAlert, but calculate() is being called inside body{} so SwiftUI can't determine how to render the View reliably. showingAlert needs to be set outside the View itself, in a modifier of some sort or perhaps a button. Hopefully someone more experienced can offer a specific solution! 3 Aug '20 Actually, there is a solution on how to fix this on this site :) https://www.hackingwithswift.com/quick-start/swiftui/how-to-fix-modifying-state-during-view-update-this-will-cause-undefined-behavior 3 Aug '20 hi, i'd recommend that you not try to pop up an Alert any time there's an illegal input in a live edit/convert like this -- it will be pretty annoying, and it just won't happen that often if you have the decimal keypad on screen. (by the way, entering a negative temperature is a problem on the decimal pad.) instead, just replace the computation of the output converstion string so that it shows there's an error. just replace `Text("\(calculate(), specifier: "%.2f")")` with a basic function call like this: ``Text(conversionResult())`` the conversionResult could look something like this: `````` func conversionResult() -> String { guard source.count > 0 else { return "0.0" } guard var inputValue = Double(source) else { return "Input Error" } // convert to C if (sourceSelection == 1) { inputValue = (inputValue - 32) * 5/9 } else if (sourceSelection == 2) { inputValue -= 273.15 } // convert to desired output base var convertedValue: Double if (resultSelection == 0) { convertedValue = inputValue } else if (resultSelection == 1) { convertedValue = (inputValue * 9/5) + 32 } else { convertedValue = inputValue + 273.15 } return String(format:"%.2f", convertedValue) }`````` that should do it for you. a comment to consider: the logic of conversion could be simplified if you took a look at Foundation's support for Measurement. Paul has some information on this. hope that helps, DMG 3 Aug '20 Thank you everyone. Much appreciated. 3

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Sponsor Hacking with Swift and reach the world's largest Swift community!

### Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

You are not logged in