**已关闭。**此问题需要debugging details。目前不接受回答。
编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答问题。
6天前关闭
这篇文章是昨天编辑并提交审查的。
Improve this question的
在我们的应用程序中,我们使用URLSession.shared.data(for:,delegate:)
和JSONDecoder进行rest API调用。在iOS>=16.1上,它可以工作。但在iOS=>17.0上使用TestFlight,它崩溃了。很难调查这个bug,因为我在MacOS 12.6上的Xcode 14.2上卡住了。我可以在服务器上确认API调用返回的statusCode为200。所以我假设问题可能是JSONDecoder因为我甚至不能捕获错误并在UI中显示它。这里有一些上下文的API代码:
func sendRequest<T: Decodable>(endpoint: Endpoint, responseModel: T.Type, allowRetry: Bool = true, authManager: AuthManager? = nil, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) async -> Result<T, RequestError> {
var urlComponents = URLComponents()
urlComponents.scheme = endpoint.scheme
urlComponents.host = endpoint.host
urlComponents.path = endpoint.path
urlComponents.queryItems = endpoint.queryItems
guard let url = urlComponents.url else { return .failure(.invalidURL(nil))}
var request = URLRequest(url: url, timeoutInterval: 5.0)
request.allHTTPHeaderFields = endpoint.header
request.httpMethod = endpoint.method.rawValue
if let body = endpoint.body {
do {
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])
} catch {
return .failure(.unexpected(error.localizedDescription))
}
}
do {
let (data, response) = try await URLSession.shared.data(for: request, delegate: nil)
guard let response = response as? HTTPURLResponse else { return .failure(.noResponse(nil))}
switch response.statusCode {
case 204:
return .success("" as! T)
case 200...299:
print("done")
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = keyDecodingStrategy
let result = try decoder.decode(responseModel, from: data)
return .success(result)
case 400:
let decoder = JSONDecoder()
let error = try decoder.decode(CheckoutError.self, from: data)
return .failure(.badRequest(error.error))
}
} catch {
guard let urlError = error as? URLError else {return .failure(.unexpected(nil))}
switch urlError.code {
case .notConnectedToInternet,
.dataNotAllowed:
return .failure(.addressUnreachable(urlComponents.url!))
case .timedOut:
return .failure(.unexpected("Request timed out. Try again"))
default:
return .failure(.unexpected(nil))
}
.failure(.addressUnreachable(urlComponents.url!))
}
}
字符串
呼叫站点:
let queryValue = "*,categories_details(*),accessories_details(*),colors_details(*),sizes_details(*),subcategories_details(*),price_ranges_details(*)"
let queryItems = ["select": queryValue]
let result = await sendRequest(endpoint: PCDBEndpoint.lookupTable(apikey: authManager.apikey, accessToken: authManager.apikey, queryItems: queryItems), responseModel: [LookupTable].self, keyDecodingStrategy: .convertFromSnakeCase)
型
有人经历过吗?你怎么修好的有没有其他方法可以在没有Xcode 15的情况下进行调试?为了避免破坏iOS 17中引入的更改,是否可以更改Xcode中的设置,使代码在iOS 17上回退到iOS 16.1。
为了解决这个问题,我尝试了以下方法:1-Symbolate Crash Log 2- Run UI Tests to lunch the app using Xcode Cloud
1-符号化崩溃日志:我已经附上了符号化的崩溃日志。看起来,问题似乎与主函数有关。我还将API调用替换为静态值。
x1c 0d1x的数据
的
这里是主要的:
import SwiftUI
@main
struct MyApp: App {
@StateObject private var appData = AppData()
@State private var lookupTablesRequest: RequestStatus = .idle
var body: some Scene {
WindowGroup {
VStack {
if (lookupTablesRequest == .idle && !appData.lookupTables.isEmpty) {
MyAppView()
.onAppear {
AppReviewRequest.resetRequestRuns()
AppReviewRequest.resetPageViews()
}
.environmentObject(appData)
} else if case .failed(let error) = lookupTablesRequest {
NoLoadedData(message: error.customMessage) {
Task {
await loadLookupTables()
}
}
} else {
VStack {
if lookupTablesRequest == .loading {
ProgressView()
.controlSize(.regular)
Text("Getting The Static Collections Ready..".uppercased())
.accessibilityIdentifier("LoaderText")
// Text(statusText2)
}
}
}
}
.task {
await loadLookupTables()
}
}
}
}
extension PrettycharmApp {
func loadLookupTables() async {
lookupTablesRequest = .loading
do {
try await appData.loadLookupTables()
lookupTablesRequest = .idle
} catch {
let requestError = error as! RequestError
lookupTablesRequest = .failed(requestError)
}
}
}
// class AppData
class AppData: ObservableObject {
@Published var lookupTables: [LookupTable] = []
@MainActor
func loadLookupTables() async throws {
let lookupTables = """
[
{
"lookup_table_id": 1,
"created_at": "2023-02-09T10:40:38.246098+00:00",
"title": "categories",
"categories_details": [
{
"created_at": "2022-06-19T15:51:12+00:00",
"category_title": "snack",
"category_id": "36515c22-c84f-4444-add4-c364ce56e162",
"lookup_table_id": 1
},
{
"created_at": "2022-06-19T15:51:49+00:00",
"category_title": "cloth",
"category_id": "f3543cc7-b9c8-443a-b266-104f85580380",
"lookup_table_id": 1
},
{
"created_at": "2022-06-19T15:52:19+00:00",
"category_title": "jewellery",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 1
}
],
"accessories_details": [],
"colors_details": [],
"sizes_details": [],
"subcategories_details": [],
"price_ranges_details": []
},
{
"lookup_table_id": 2,
"created_at": "2023-02-09T10:42:39.024016+00:00",
"title": "subcategories",
"categories_details": [],
"accessories_details": [],
"colors_details": [],
"sizes_details": [],
"subcategories_details": [
{
"subcategory_id": "08bfd883-dc24-4310-9a46-6f0bd2bea5a2",
"created_at": "2022-04-29T05:26:29+00:00",
"subcategory_title": "1-piece set",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "89aa47c7-fcdb-4725-90d2-a8a91acff997",
"created_at": "2022-04-29T05:14:51+00:00",
"subcategory_title": "anklets",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "a7757d8f-61de-4241-b04e-d7f937da25f7",
"created_at": "2022-04-29T05:14:40+00:00",
"subcategory_title": "pendants",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "b6f4dad2-5dad-4dd4-8a45-e63022458dbd",
"created_at": "2022-04-29T05:15:18+00:00",
"subcategory_title": "bracelets",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "bf638ab8-1508-42c1-bcae-65efe99494ac",
"created_at": "2022-04-29T05:26:45+00:00",
"subcategory_title": "2-piece set",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "c465eff8-ecb7-4657-998d-a0977a4c5c9a",
"created_at": "2022-04-29T05:14:29+00:00",
"subcategory_title": "bangles",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "d5c987f4-0743-4160-8091-f243bf40f534",
"created_at": "2022-04-29T05:14:18+00:00",
"subcategory_title": "rings",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "d60197c8-7892-4918-b601-b4bfe02fd718",
"created_at": "2022-04-29T05:15:02+00:00",
"subcategory_title": "necklaces",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "d913f0de-e387-4540-b9af-c254e0d9a9db",
"created_at": "2022-04-29T05:23:12+00:00",
"subcategory_title": "3-piece set",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "fe19b1ab-2a67-42d5-93e6-b21adb93c972",
"created_at": "2022-04-29T05:27:14+00:00",
"subcategory_title": "earrings",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
},
{
"subcategory_id": "8de270ee-3659-455b-abc8-650999189b86",
"created_at": "2023-02-07T11:16:50.106686+00:00",
"subcategory_title": "4-piece set",
"category_id": "ed348275-76e6-4967-b5d8-c625e1b8402d",
"lookup_table_id": 2
}
],
"price_ranges_details": []
},
{
"lookup_table_id": 3,
"created_at": "2023-02-09T10:43:16.1912+00:00",
"title": "accessories",
"categories_details": [],
"accessories_details": [
{
"accessory_id": "80b563f6-5388-4b7b-9686-fc68acc0ea98",
"created_at": "2022-06-10T18:53:17+00:00",
"accessory_title": "extensions",
"lookup_table_id": 3
},
{
"accessory_id": "2177c309-1a04-4055-8e4b-b5d5f0d1069a",
"created_at": "2022-06-10T18:53:37+00:00",
"accessory_title": "wiper",
"lookup_table_id": 3
},
{
"accessory_id": "fd424569-9c81-4764-b5aa-2ab3767db35d",
"created_at": "2022-06-10T18:53:47+00:00",
"accessory_title": "brush",
"lookup_table_id": 3
},
{
"accessory_id": "d296a7bc-a685-4c50-ada1-c076188aed7b",
"created_at": "2023-01-31T17:10:46.427525+00:00",
"accessory_title": "none",
"lookup_table_id": 3
}
],
"colors_details": [],
"sizes_details": [],
"subcategories_details": [],
"price_ranges_details": []
},
{
"lookup_table_id": 4,
"created_at": "2023-02-09T10:43:38.885198+00:00",
"title": "colors",
"categories_details": [],
"accessories_details": [],
"colors_details": [
{
"created_at": "2022-06-19T12:51:57+00:00",
"color_title": "silver",
"color_id": "f579a3e6-758d-431a-89f3-9ebdabe43bfa",
"color_value": {
"b": 192,
"g": 192,
"r": 192
},
"lookup_table_id": 4
},
{
"created_at": "2022-04-29T04:59:04+00:00",
"color_title": "white gold",
"color_id": "ac6ba2ee-ef7e-4c6e-b2d6-774d38f18e39",
"color_value": {
"b": 142,
"g": 165,
"r": 187
},
"lookup_table_id": 4
},
{
"created_at": "2022-04-29T04:58:24+00:00",
"color_title": "gold",
"color_id": "7e97e6ab-29d8-4af3-a32d-858c615858b2",
"color_value": {
"b": 0,
"g": 215,
"r": 255
},
"lookup_table_id": 4
},
{
"created_at": "2022-04-29T04:58:41+00:00",
"color_title": "rose gold",
"color_id": "bcb2b41e-4009-46b5-b4d9-38a78409152e",
"color_value": {
"b": 119,
"g": 108,
"r": 183
},
"lookup_table_id": 4
},
{
"created_at": "2022-04-29T05:40:31+00:00",
"color_title": "mixed",
"color_id": "82f1b68d-9a23-4c86-8eeb-1f5756d4ffa9",
"color_value": {
"b": 225,
"g": 231,
"r": 226
},
"lookup_table_id": 4
}
],
"sizes_details": [],
"subcategories_details": [],
"price_ranges_details": []
},
{
"lookup_table_id": 5,
"created_at": "2023-02-09T10:44:13.027229+00:00",
"title": "sizes",
"categories_details": [],
"accessories_details": [],
"colors_details": [],
"sizes_details": [
{
"created_at": "2022-04-29T04:44:58+00:00",
"size_title": "s",
"size_id": "bdec8999-6319-45e2-b8dc-2199e37531e1",
"lookup_table_id": 5
},
{
"created_at": "2022-04-29T04:45:43+00:00",
"size_title": "m",
"size_id": "1e8afcb4-5a25-4076-bc1d-16db98ef2e70",
"lookup_table_id": 5
},
{
"created_at": "2022-04-29T04:46:05+00:00",
"size_title": "l",
"size_id": "94c9af88-8830-40bb-adf8-8cbb005b2aa8",
"lookup_table_id": 5
},
{
"created_at": "2022-04-29T04:46:27+00:00",
"size_title": "xl",
"size_id": "417d1064-5027-4e2c-ad45-965f7e6bf3f4",
"lookup_table_id": 5
},
{
"created_at": "2022-04-29T04:46:37+00:00",
"size_title": "xs",
"size_id": "c48aafdf-7ad5-4fc6-accb-1d3de0f771e6",
"lookup_table_id": 5
},
{
"created_at": "2023-01-31T17:11:47.711272+00:00",
"size_title": "one size fits all",
"size_id": "2da33760-0e00-4afd-9419-9f366bcc7018",
"lookup_table_id": 5
}
],
"subcategories_details": [],
"price_ranges_details": []
},
{
"lookup_table_id": 6,
"created_at": "2023-02-09T10:44:30.403458+00:00",
"title": "price_ranges",
"categories_details": [],
"accessories_details": [],
"colors_details": [],
"sizes_details": [],
"subcategories_details": [],
"price_ranges_details": [
{
"id": 1,
"created_at": "2023-02-09T12:11:16.302103+00:00",
"range": [
0,
50
],
"lookup_table_id": 6
},
{
"id": 2,
"created_at": "2023-02-09T12:11:52.858243+00:00",
"range": [
50,
100
],
"lookup_table_id": 6
},
{
"id": 3,
"created_at": "2023-02-09T12:12:17.185552+00:00",
"range": [
100,
150
],
"lookup_table_id": 6
},
{
"id": 4,
"created_at": "2023-02-09T12:12:40.797355+00:00",
"range": [
150,
250
],
"lookup_table_id": 6
},
{
"id": 5,
"created_at": "2023-02-09T12:13:06.281451+00:00",
"range": [
250,
400
],
"lookup_table_id": 6
},
{
"id": 6,
"created_at": "2023-02-09T12:13:24.880879+00:00",
"range": [
400,
600
],
"lookup_table_id": 6
},
{
"id": 7,
"created_at": "2023-02-09T12:14:08.062709+00:00",
"range": [
600
],
"lookup_table_id": 6
}
]
}
]
"""
let jsonData = Data(lookupTables.utf8)//try JSONEncoder().encode(lookupTables.utf8)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let lookupTablesList = try decoder.decode([LookupTable].self, from: jsonData)
self.lookupTables = lookupTablesList
}
}
型
2-使用Xcode Cloud运行UI测试:
在Xcode云上,操作系统配置设置为iOS 17。我得到了这个测试失败,这似乎证实了我在运行iOS 17的真实的设备上遇到的运行时错误。
任何帮助,以解决这个问题将有很长的路要走。谢谢。
1条答案
按热度按时间8aqjt8rx1#
您可能希望从可能崩溃的代码部分开始:
字符串
如果
body
包含非plist值,则会崩溃。(Plist-values是数组、字典、字符串、数字、布尔值和NSNull,不能包含NaN或无穷大。除非传递.fragmentsAllowed
,否则顶级对象必须是数组或字典。)这是应该避免JSONSerialization而首选JSONEncoder的一个原因。您的代码似乎假定它会抛出错误,但它实际上抛出了一个Swift无法捕获的异常。这是我首先要查看的地方。我会查看PCDBEndpoint,并确保在所有情况下,它返回的每个属性都是一个plist值。如果你在这个主体中包含Apple类型,这肯定是我要查找错误的地方,因为内部类型可能已经更改,或者值可能是NaN或无穷大。
有关详细信息,请参见
data(withJSONObject:options:)
:如果
obj
无法生成有效的JSON,JSONSerialization
会抛出异常。此异常发生在解析之前,表示编程错误,而不是内部错误。在调用此方法之前,您应该检查输入是否可以使用isValidJSONObject(_:)
生成有效的JSON。参见
JSONSerialization
:要将Foundation对象转换为JSON,对象必须具有以下属性:
调用
isValidJSONObject(_:)
或尝试转换是判断JSONSerialization类是否可以将给定对象转换为JSON数据的明确方法。型
这将在T不是String的任何情况下崩溃(在这种情况下它不是)。这不太可能是原因,但在服务器意外返回204时崩溃您的应用程序并不是一个好主意。
型
这永远不会崩溃,因为前面已经检查过使用
if-let
,但我建议在这里使用您的本地url
而不是!
。您已经完成了if-let
工作;您可能会从中受益。