I recently started with iOS development, and I'm currently working on adding new functionality to an existing app. For this feature I need to obtain a JSON
file from a web server. However, if the server is unreachable (no internet/server unavailable/etc), a local JSON
needs to be used instead.
In my current implementation I tried using a do catch
block, but if there's no internet connection, the app just hangs instead of going to the catch
block. JSON
parsing and local data reading seem to work fine, the problem is likely in the GET
method, as I tried to define a callback to return the JSON
data as a separate variable, but I'm not sure if that's the correct way.
What is the best way to handle this scenario?
let url = URL(string: "https://jsontestlocation.com") // test JSON
do {
// make a get request, get the result as a callback
let _: () = getRemoteJson(requestUrl: url!, requestType: "GET") {
remoteJson in
performOnMainThread {
self.delegate.value?.didReceiveJson(.success(self.parseJson(jsonData: remoteJson!)!))
}
}
}
catch {
let localFile = readLocalFile(forName: "local_json_file")
let localJson = parseJson(jsonData: localFile!)
if let localJson = localJson {
self.delegate.value?.didReceiveJson(.success(localJson))
}
}
getRemoteJson()
implementation:
private func getRemoteJson(requestUrl: URL, requestType: String, completion: @escaping (Data?) -> Void) {
// Method which returns a JSON questionnaire from a remote API
var request = URLRequest(url: requestUrl) // create the request
request.httpMethod = requestType
// make the request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// check if there is any error
if let error = error {
print("GET request error: \(error)")
}
// print the HTTP response
if let response = response as? HTTPURLResponse {
print("GET request status code: \(response.statusCode)")
}
guard let data = data else {return} // return nil if no data
completion(data) // return
}
task.resume() // resumes the task, if suspended
}
parseJson()
implementation:
private func parseJson(jsonData: Data) -> JsonType? {
// Method definition
do {
let decodedData = try JSONDecoder().decode(JsonType.self, from: jsonData)
return decodedData
} catch {
print(error)
}
return nil
}