swift – API calls break on iOS 17


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.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img