In our app, we are making rest API calls with URLSession.shared.data(for:,delegate:) and JSONDecoder. On iOS>=16.1, it works. But on iOS=>17.0 using TestFlight, it crashes. It’s hard investigate this bug cause I’m stuck on Xcode 14.2 on MacOS 12.6. I can confirm on the server that the API call returns a statusCode of 200. So I assume the issue it might be the JSONDecoder since I can’t even catch the error and show it in my UI.
Here’s some API code for context:
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!))
}
}
The call site:
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)
Has anyone experienced this? How did you fix it? Is there an alternative way to debug this without Xcode 15? To avoid breaking changes introduced in iOS 17, is it possible to change a setting in Xcode that would make the code fallback to IOS 16.1 on iOS 17.




