swift iOS 17上的API调用中断[关闭]

3bygqnnd  于 2024-01-05  发布在  Swift
关注(0)|答案(1)|浏览(143)

**已关闭。**此问题需要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的真实的设备上遇到的运行时错误。
任何帮助,以解决这个问题将有很长的路要走。谢谢。

8aqjt8rx

8aqjt8rx1#

您可能希望从可能崩溃的代码部分开始:

request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])

字符串
如果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,对象必须具有以下属性:

  • 顶级对象是NSArray或NSDictionary,除非您设置了fragmentsAllowed选项。
  • 所有对象都是NSString、NSNumber、NSArray、NSDictionary或NSNull的示例。
  • 所有字典键都是NSString的示例。
  • 数字既不是NaN也不是无穷大。

调用isValidJSONObject(_:)或尝试转换是判断JSONSerialization类是否可以将给定对象转换为JSON数据的明确方法。

return .success("" as! T)


这将在T不是String的任何情况下崩溃(在这种情况下它不是)。这不太可能是原因,但在服务器意外返回204时崩溃您的应用程序并不是一个好主意。

return .failure(.addressUnreachable(urlComponents.url!))


这永远不会崩溃,因为前面已经检查过使用if-let,但我建议在这里使用您的本地url而不是!。您已经完成了if-let工作;您可能会从中受益。

相关问题