Swift Catch Enum Case with Binding

Swift catch enum case with binding

If I understand you correctly, you want a variable inside a catch to be the specific error case of a specific type of error.

If so, you can do this:

do {
try something()
} catch let err1 as MyError where err1 == .error1 {
print(err1)
} catch {
print(error)
}

Binding to an associated value of an enum

You can extend your enumeration and add a text property with a getter and a setter:

extension Choice {
var text: String {
get {
switch self {
case let .one(string): return string
case let .two(string): return string
}
}
set {
switch self {
case .one: self = .one(newValue)
case .two: self = .two(newValue)
}
}
}
}

Then you can simply pass the text property:

TextField("", text: $choice.text) 

How can I use enum to Binding data in SwiftUI?

Using a brandProxy to maintain the integrity of the other Car variables

import SwiftUI
enum Brand: Int, CaseIterable, Codable {
case toyota = 0
case mazda
case suzuki
case unknown

func description() -> String {
var result = "unknown"
switch self {
case .toyota:
result = "toyota"
case .mazda:
result = "mazda"
case .suzuki:
result = "suzuki"
case .unknown:
result = "unknown"
}
return result
}
}
struct CarView: View {
//This makes it mutable
@State var car: Car
var brandProxy: Binding<Int> {
Binding<Int>(
get: {
car.brand.rawValue
},
set: {
car.brand = Brand(rawValue: $0) ?? Brand.unknown
}
)
}
var body: some View {
VStack{
Text(car.brand.description())
SomeView(selectedIndex: brandProxy)
}
}
}

How to create a Binding to an enum in Swift?

As an alternative to @Binding you can use @Published in @ObservableObject:

class ViewModel: ObservableObject {
@Published var lifeEvent: LifeEvent? {
didSet { // or alternatively willSet (depending on the use case)
// do whatever you need just after the lifeEvent is changed
}
}
}
struct TimeSpanEditView: View {
@ObservedObject private var viewModel = ViewModel()
...
}

And access your binding like this:

self.$viewModel.lifeEvent

Binding to an associated value of an enum that has different types of associated values

Indeed, having several very similar properties is a code smell, as well as the fact that those properties were added just because they are needed by the UI layer.

However, since you already have the switch over the value type, you can push the logic for the binding to that (UI) layer. Here's a possible implementation:

struct ValueView: View {
let name: String
@Binding var value: Value

var body: some View {
HStack {
switch value {
case .none:
Spacer()
case let .bool(bool):
Toggle(name, isOn: Binding(get: { bool }, set: { value = .bool($0) } ))
case let .int(int):
Stepper("\(int)", value: Binding(get: { int }, set: { value = .int($0) }))
case let .float(float):
Text(float.description)
case let .string(string):
Text(string)
}
}
}
}

I also took the liberty of extracting the code to a dedicated view and decoupling that view from the Node type, this is more idiomatic in SwiftUI and makes your code more readable and easier to maintain.

With the above in mind, ContentView simply becomes:

Usage:

struct ContentView: View {
@StateObject private var model = Model()

var body: some View {
VStack {
ScrollView {
Text(model.jsonString)
}

List($model.data, id: \.name, children: \.children) { $node in
ValueView(name: node.name, value: $node.value)
}
}
}
}

, and you can safely delete the "duplicated" properties from the Value enum.

Use Guard to trap all enum states other than one

It is impossible to negate a case statement.

You either need to use your if statement, or make the enumeration Equatable, in which case you would just drop the case keyword.

guard foundTransition.validToObject.isInSituation != .notInUse

Alternatively, you can use a guard statement that is backed by a switch or if. But you'll never get rid of them! /p>

guard ({
if case .notInUse = foundTransition.validToObject.isInSituation {
return false
}
return true
} ()) else {
fatalError("Transition: The toObject is already in a situation")
}

Swift Catch Pattern that binds the error to a variable

The syntax used in a catch line is exactly the same pattern syntax used in the case of a switch. If you know how to write a case you know how to write a catch.

So, for example, you complain:

} catch let decodingError is DecodingError {  // THIS IS NOT VALID

Right. But this is valid:

} catch let decodingError as DecodingError { 

Oh what a difference one letter makes.

swift enum get the associated value of multiple case with same parameters in single switch-case

You can put multiple enum values in the same case line, but you have to move the let into the ():

var value: Double {
switch self {
case .width(let value), .height(let value), .xxxxx1(let value):
return value
}
}

You might want to put each enum value on a separate line:

var value: Double {
switch self {
case .width(let value),
.height(let value),
.xxxxx1(let value):
return value
}
}

Unfortunately, that's about as elegant as it gets with enums with associated values. There's no way to get the associated value without explicitly listing the enums.

You can only combine values in the same line that have the same type of associated value, and all of the values have to bind to the same variable name. That way, in the code that follows, you know that the value is bound and what its type is no matter which enum pattern matched.



Related Topics



Leave a reply



Submit