在 Swift + SwiftUI 中处理错误的好习惯
Posted
技术标签:
【中文标题】在 Swift + SwiftUI 中处理错误的好习惯【英文标题】:A good practice to handle errors in Swift + SwiftUI 【发布时间】:2021-12-30 10:56:59 【问题描述】:我目前正在 Swift Concurrency 中迈出第一步(使用 async/await/actors)。在集成任务中处理的函数时(通过 Swift 并发),我目前正在使用这个概念来处理错误:
Model.swift
public func submit() async
self.isSubmitting = true
defer self.isSubmitting = false
do
let result = await worker()
catch
self.hasErrorOccurred = true
self.errorDescription = error.localizedDescription
self.hasSubmittedSuccessfully = true
ContentView.swift
struct ContentView: View
@ObservedObject var model: Model
var body: some View
VStack
Button(action:
Task
await model.submit()
) Text("Submit")
if model.hasErrorOccurred
Text(model.errorDescription)
if model.hasSubmittedSuccessfully
Text("Success")
我想知道这是否是用这种方法处理错误或成功反馈的好习惯。你是怎么处理的?
【问题讨论】:
我正在开发一个小型错误处理框架,该框架将它们向上传递到视图层次结构,直到视图处理它们。今晚我将添加对“Alertable”错误的支持,以及一个在触发错误时自动显示警报的 ViewModifier。你可以在这里找到 WIP github.com/EmilioPelaez/ErrorHierarchy。如果您想进一步讨论,请随时与我联系 :) 【参考方案1】:所有这些布尔标志都不是一个好习惯。
我的建议是一个带有关联值的枚举
enum WorkResult
case none, success(String), failure(Error)
在Model
中采用ObservableObject
,声明@Published
属性并在submit
方法中分配案例。这将更新视图。这个简单的例子在两秒后返回字符串“Hello”。
@MainActor
class Model : ObservableObject
@Published var submission : WorkResult = .none
public func submit() async
do
let result = try await worker()
submission = .success(result)
catch
submission = .failure(error)
func worker() async throws -> String
try await Task.sleep(nanoseconds: 2_000_000_000)
return "Hello"
在视图switch
上枚举并处理案例
struct ContentView : View
@StateObject private var model = Model()
var body: some View
VStack
Button(action:
Task
await model.submit()
) Text("Submit")
switch model.submission
case .success(let result): Text(result)
case .failure(let error): Text(error.localizedDescription)
default: EmptyView()
【讨论】:
非常好的提议!以上是关于在 Swift + SwiftUI 中处理错误的好习惯的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift UIKit Map 组件中处理 SwiftUI 中的触摸手势?
Swift / SwiftUI:如何检查环境 /binding var 是不是为空字符串(.isEmpty 出现构建错误)