我創建了一個手表應用程式,它對我來說很好用,而其他人則指出發生了崩潰。因此,由于我無法重新創建,因此我從 xcode 中找到了該構建的崩潰日志,崩潰日志如下所示,
Incident Identifier: AE2591FC-4E97-4EE4-8E9A-3CA6480A2EDF
Hardware Model: Watch5,9
Process: watch Extension [276]
Path: /private/var/containers/Bundle/Application/E2F3129B-4EF2-4C80-A0D4-82D246A39F32/watch.app/PlugIns/watch Extension.appex/watch Extension
Identifier: //app id
Version: 7 (4.1.0)
AppVariant: 1:Watch5,9:7
Beta: YES
Code Type: ARM (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: // [378]
Date/Time: 2021-11-04 16:38:59.1335 0530
Launch Time: 2021-11-04 16:31:54.0000 0530
OS Version: Watch OS 7.3.3 (18S830)
Release Type: User
Baseband Version: n/a
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000022ce5c88
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [276]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 libswiftCore.dylib 0x22ce5c88 _assertionFailure(_:_:file:line:flags:) 356 (AssertCommon.swift:132)
1 libswiftCore.dylib 0x22d3d12c swift_unexpectedError 300 (ErrorType.swift:188)
2 watch Extension 0x04488074 closure #1 in OtpView.fetchProfile() 1232 (OtpView.swift:203)
3 watch Extension 0x0443c47c specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) 1120 (Inteceptor.swift:0)
4 watch Extension 0x0443dc80 partial apply for specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) 72 (<compiler-generated>:0)
5 watch Extension 0x04438a38 thunk for @escaping @callee_guaranteed () -> () 20 (<compiler-generated>:0)
6 libdispatch.dylib 0x2a5901bc _dispatch_client_callout 16 (object.m:559)
7 libdispatch.dylib 0x2a593344 _dispatch_continuation_pop 492 (inline_internal.h:2548)
8 libdispatch.dylib 0x2a5a3eb0 _dispatch_source_invoke 1272 (source.c:570)
9 libdispatch.dylib 0x2a59ce58 _dispatch_main_queue_callback_4CF 556 (inline_internal.h:2589)
10 CoreFoundation 0x20110eec __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ 12 (CFRunLoop.c:1790)
11 CoreFoundation 0x2010b428 __CFRunLoopRun 2452 (CFRunLoop.c:3118)
12 CoreFoundation 0x2010a574 CFRunLoopRunSpecific 572 (CFRunLoop.c:3242)
13 GraphicsServices 0x348904c0 GSEventRunModal 160 (GSEvent.c:2259)
14 UIKitCore 0x24f95adc -[UIApplication _run] 1104 (UIApplication.m:3253)
15 UIKitCore 0x24f9afdc UIApplicationMain 140 (UIApplication.m:4707)
16 WatchKit 0x2703dc30 WKApplicationExtensionMain 312 (main.m:131)
17 SwiftUI 0x28a3b628 runApp<A>(_:) 196 (WatchKitRenderer.swift:34)
18 SwiftUI 0x28957d6c static App.main() 80 (App.swift:113)
19 watch Extension 0x044288c8 $main 24 (<compiler-generated>:10)
20 watch Extension 0x044288c8 main 36 (Observables.swift:0)
21 WatchKit 0x26f6694c WKExtensionMain 608 (main.m:102)
22 libdyld.dylib 0x3591191c start 4
...
在此處輸入圖片說明
我不確定錯誤發生在哪里以及為什么會發生。任何人都可以指導我完成這個嗎?
我針對相關問題的快速代碼如下所示,
/*
* ? Copyrights
* All Rights Reserved.
*
*
*
*
*
*
*
*
*/
import SwiftUI
struct OtpView: View {
private let placeholder: String = "Enter the 6 digit OTP here"
@State private var input:String = "Enter the 6 digit OTP here";
@State private var navigateToNext: Bool = false;
@State private var isVisible: Bool = false;
@State private var alertMessage: String = "";
@State private var isFetching: Bool = false;
init(){
input=self.placeholder;
}
var body: some View {
// NavigationView{
ZStack{
AlertView(isVisible: $isVisible,
message: self.alertMessage,
onHide: {
if self.isVisible {
self.isVisible.toggle();
}
})
if self.isFetching {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
}
GeometryReader{
geometry in
let width = geometry.size.width;
let height = geometry.size.height;
VStack(alignment:.leading){
Text(input)
.font(.system(size:14.0,design: .rounded))
.multilineTextAlignment(.trailing)
.frame(width:width)
.lineLimit(1)
NavigationLink(destination:HomeView(),
isActive: $navigateToNext){
}
.frame(width:0,height:0)
HStack(){
Spacer()
GradientButton(buttonTitle: "NEXT"){
self.validateOtp()
}
Spacer()
}
.frame(width: width)
.padding([.bottom,.top], 5.0)
Divider()
Spacer()
VStack(){
ForEach(buttonList, id: \.self){
row in
HStack(){
ForEach(row, id:\.self){
button in
Button(action: {
if self.input == self.placeholder {
if button != "del"{
input = button;
}
}else{
if button != "del" {
input.count != 6 ?
input = button : nil
}else{
if input.count == 1 {
input = self.placeholder
}else{
input = String(input.dropLast())
}
}
}
}){
if button != "del" {
Text(button)
.font(.system(size:14.0,design: .rounded))
.frame(minWidth:(width/4), idealWidth: (width/4), maxWidth:(width/4),
maxHeight:.infinity)
} else {
Image("Delete")
.resizable()
.frame(width:18, height:16)
.padding()
}
}
.frame(minWidth:(width/4), idealWidth: (width/4), maxWidth:width/3-10,
minHeight:height/6,
idealHeight: height/6,
maxHeight: height/6)
.cornerRadius(50.0)
.buttonStyle(PlainButtonStyle())
if button != "3" && button != "6" && button != "9" && button != "del" {
Spacer()
}
}
}
}
}
}
}
.blur(radius: isVisible || self.isFetching ? 3.0 : 0)
.disabled(isVisible)
}
// }
.navigationBarBackButtonHidden(false)
.navigationTitle("OTP")
.onDisappear(perform: {
print("GOINF FROM OTP")
})
}
func validateOtp(){
if input != self.placeholder && input.count == 6 && isStringContainsOnlyNumbers(string:input){
self.isFetching.toggle();
let requestHeader = getRequestHeader(action:”NO_ACTION”);
guard let id = requestHeader[“id”] else {
return;
}
let request = [
“Validate”:[
“name”:GlobalData.name,
"deviceId":"N/A",
"detail”: [
"action”:”NO_ACTION”,
"otp":self.input
],
],
"requestHeader": requestHeader
] as [String : Any]
useInteceptor(urlString: ncellUrls[“URL1”] ?? "",method: "POST", requestBody: request){ data, error, displayCode in
self.isFetching.toggle();
if let data = data {
let validateOtpResponse = try! JSONDecoder().decode(ValidateOtpResponse.self, from: data);
if let userAuth = validateOtpResponse.validateOTPResponse {
self.isFetching.toggle();
self.fetchProfile();
// self.navigateToNext.toggle();
}
} else {
self.alertMessage = getErrorMessage(code: displayCode)
self.isVisible.toggle();
}
}
}else{
self.alertMessage = "Please enter a valid Otp to proceed."
self.isVisible.toggle();
}
}
func fetchProfile(){
let request = [
“getProfile”:[
“name”:GlobalData.name,
“Id”: "1",
],
"requestHeader": getRequestHeader(action:”ACTION1”)
]
useInteceptor(urlString: ncellUrls[“URL2”] ?? "",method: "POST", requestBody: request){ data, error, displayCode in
self.isFetching.toggle();
if let data = data {
let profile = try! JSONDecoder().decode(ProfileResponse.self, from: data);
if let ratePlanDetails = profile.response?.detail {
self.navigateToNext.toggle();
}
} else {
self.alertMessage = getErrorMessage(code: displayCode)
self.isVisible.toggle();
}
}
}
}
struct OtpView_Previews: PreviewProvider {
static var previews: some View {
OtpView()
}
}
uj5u.com熱心網友回復:
無關,但在 Swift 中,不需要;在行尾。
讓我們閱讀崩潰日志:
2 watch Extension 0x04488074 closure #1 in OtpView.fetchProfile() 1232 (OtpView.swift:203)
3 watch Extension 0x0443c47c specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) 1120 (Inteceptor.swift:0)
4 watch Extension 0x0443dc80 partial apply for specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) 72 (<compiler-generated>:0)
那是有趣的部分(頂部有方法名稱的部分),您可以從底部閱讀它們。
所以在Interceptor.swift, 方法useInteceptor(urlString:method:requestBody:completionHandler:)在某個時候被呼叫。
在這個中,有一個closure(或多個),但至少在第一個 ( closure #1) 中completionHandler,即您在檔案中呼叫fetchProfile的OptView類OptView.swift。
在那里,在第 203 行,它是導致崩潰的那條線。
我們來分析一下罪魁禍首:
let profile = try! JSONDecoder().decode(ProfileResponse.self, from: data)
在這里,可能的崩潰是因為try!.
你為什么用try!寫的,而不是do/ try/ catch?你知道你為什么!在這里使用 force unwrap嗎?這是什么意思?
這意味著如果拋出錯誤,只會使應用程式崩潰。
因此,如果發生崩潰,這是預期的行為,因為您明確地寫了“如果拋出錯誤,則在此處崩潰”。
那么,現在,為什么會decode(_:from:)崩潰?
我不知道是什么ProfileResponse,但是該方法可能會引發錯誤,因為您沒有指定 JSON 中的值可以為空,JSON 中的值可以省略,因為接收到的 JSON 存在另一個問題, 或者 JSON 無效。
或者,因為您的 API 給出了錯誤的價值。有時,當 API 遇到錯誤時,它們可能會回應:{"error": "some reason why it failed"}. 這是一個有效的 JSON,但我認為ProfileResponse不會像那樣。
現在,為什么它給出了錯誤的回應,這取決于您的 Web API,檢查檔案,檢查 API 開發人員是否有可能的回應:您是否使用了錯誤的引數,您是否陷入了后端未處理的情況?
所以當你用 寫那行時try!,你決定告訴:“不要擔心回應,如果有回應,我確信它可以被解碼成一個ProfileResponse物件。相信我,我知道什么我在做,我保證它永遠有效,如果不是這樣,只是崩潰,那將證明我錯了,但請放心,我對自己很有信心”。是的,就是這個意思try!。
如果你不想崩潰,不使用!,寫一個屬性do/ try/ catch。
do {
let profile = try JSONDecoder().decode(ProfileResponse.self, from: data)
if let ratePlanDetails = profile.response?.detail {
self.navigateToNext.toggle()
}
} catch {
print("Oops, there was an error while decoding ProfileResponse: \(error)")
print("And the API response was: \(String(data: data, encoding: .utf8) ?? "unknown data")")
}
現在,至于為什么您的回應無效,這取決于您的除錯:嘗試使用特定引數、特定情況等重現它)。我們無法猜測出了什么問題,也無法猜測回傳 API 的原因。一旦您知道您的 API 發回的真實回應是什么,并且不知道如何處理它,您可以在 SO 上提出一個新問題,我們可能會幫助您,但在這一點上,我們無能為力你的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/354731.html
