如何在SwiftUI内购退款请求中捕获并展示错误信息
问题:SwiftUI退款请求错误捕获与Alert展示
我正在修改Apple官方《Food Truck: Building a SwiftUI Multiplatform App》示例中的退款请求逻辑,需要捕获退款请求错误。但Apple的示例未展示错误捕获方法,给学习者造成了困扰。
目前我能在代码标注“catch refund errors here”的result中看到错误,打印信息如下:
refund error Binding<Optional>(transaction: SwiftUI.Transaction(plist: []), location: SwiftUI.StoredLocation<Swift.Optional<Swift.Error>>, _value: nil) failure(StoreKit.Transaction.RefundRequestError.duplicateRequest) Transaction.RefundError RefundRequestError
我的需求是:如何将错误(比如duplicateRequest)的localizedDescription展示到Alert中?
问题在于成功分支未使用do/catch块就直接跳转,我尝试用error、gotError存储错误,但不清楚result的类型。相关代码如下:
struct RefundView: View { @State private var recentTransactions: [StoreKit.Transaction] = [] @State private var selectedTransactionID: UInt64? @State private var refundSheetIsPresented = false @State private var error: Error? @State private var refundError: Bool = false @State var gotError: String = "" @Environment(\.dismiss) private var dismiss var body: some View { List(recentTransactions, selection: $selectedTransactionID) { transaction in TransactionRowView(transaction: transaction) } .safeAreaInset(edge: .bottom) { VStack(spacing: 0) { Text("Select a purchase to refund") .font(.subheadline) .foregroundColor(.secondary) .padding() Button { refundSheetIsPresented = true } label: { Text("Request a refund") .bold() .padding(.vertical, 5) .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) .padding([.horizontal, .bottom]) .disabled(selectedTransactionID == nil) } } .task { @MainActor in for await transaction in StoreKit.Transaction.all { recentTransactions.append(transaction.unsafePayloadValue) } } .refundRequestSheet( for: selectedTransactionID ?? 0, isPresented: $refundSheetIsPresented ) { result in if case .success(.success) = result { dismiss() } // ******* catch refund errors here ******* self.error = error refundError.toggle() // $gotError = result print("refund error \($error)") print(result) print("Transaction.RefundError \(Transaction.RefundRequestError)") } .navigationTitle("Refund Purchase") .alert("Refund error: \(gotError)", isPresented: $refundError, actions: {}) } }
解决方案
1. 明确result的类型
refundRequestSheet的回调参数result类型是Result<StoreKit.Transaction.RefundRequestStatus, Error>:
.success的关联值是RefundRequestStatus枚举,包含.success(退款请求提交成功)、.userCancelled(用户取消操作)两种情况.failure的关联值就是具体的Error对象,比如你遇到的RefundRequestError.duplicateRequest
2. 正确解析错误并触发Alert
修改回调逻辑,通过模式匹配捕获错误,提取localizedDescription并更新状态变量:
.refundRequestSheet( for: selectedTransactionID ?? 0, isPresented: $refundSheetIsPresented ) { result in switch result { case .success(let status): if status == .success { dismiss() // 退款请求提交成功,关闭页面 } // 用户取消操作时可根据需求添加提示,或不做处理 case .failure(let error): gotError = error.localizedDescription refundError = true // 触发错误Alert } }
3. 优化Alert显示效果
调整Alert代码,让错误信息展示更清晰:
.alert("退款失败", isPresented: $refundError) { Button("确定", role: .cancel) {} } message: { Text(gotError) }
4. 清理无效代码
删除原代码中self.error = error这类无效赋值,以及$gotError = result这种类型不匹配的错误写法。
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

