My app needs to be able to decode multiple JSON files (around 50) one at a time. Here is the code I currently use to do this:
class Api {
static var Acceptable: Bool = true //Acceptable range to reload sites
static var order = 1
//From: https://stackoverflow.com/questions/38469648/unexpected-non-void-return-value-in-void-function-in-new-swift-class
//Also from: https://stackoverflow.com/questions/65999965/how-to-pass-arguments-into-a-function-with-completion-swift (input part)
func CoordsUpdate(completion: @escaping ((Double, Double, String) -> Void)) {
var states = [ "AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]
for state in states {
let URL = String("https://waterservices.usgs.gov/nwis/iv/?format=json&indent=off&stateCd=\(state)¶meterCd=00065&siteStatus=active")
print("states URL:", URL)
Api().getCoordinates(inputurl: URL) { lat, long, name in
completion(lat, long, name)
return
}
repeat {
print("waiting for processing", state)
//sleep(UInt32(0.1)) //waits for 0.1 sec
sleep(1)
} while (Api.order < 1)
print("coordsupdate done for:", state)
states.removeFirst()
print("states left to process:", states)
}
print("done buh")
}
func getCoordinates(inputurl: String, completion: @escaping ((Double, Double, String) -> Void)) {
Api.order = 0
print("order is now 0")
print("input:", inputurl)
let url = URL(string: inputurl)!
print("Fetching data")
//Timer from: https://stackoverflow.com/questions/24755558/measure-elapsed-time-in-swift
let start = DispatchTime.now()
//Error handling from: https://www.hackingwithswift.com/forums/swift/urlsession-error/780
URLSession.shared.dataTask(with: url) { [self] data, response, error in
if let data = data {
print("Data fetched", url)
print("data size:",data)
let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds // <<<<< Difference in nano seconds (UInt64)
var timeInterval = Double(nanoTime) / 1_000_000_000 // Technically could overflow for long running tests
timeInterval = ((round(timeInterval * 100)) / 100) //Rounds to 2 decimals
print("Time to fetch data: \(timeInterval) seconds")
let posts = try! JSONDecoder().decode(Post.self, from: data)
print("JSON processed:", url)
let postarray = (posts.value?.timeSeries) //all sites in an array (not including header/query info)
//from https://stackoverflow.com/questions/63609283/swift-for-in-loop-requires-deepspeechtokenmetadata-to-conform-to-sequence (or not idk)
var numsadded = 0
var numsremoved = 0
for item in (postarray!) {
//From: https://stackoverflow.com/questions/42523769/how-to-parse-json-data-and-eliminate-duplicates-in-swift
for _ in nome.names {
let name = (item.sourceInfo?.siteName)
// print("nome:", name!)
if nome.names.contains(name!) {
// print("duplicate")
numsremoved += 1
break
} else {
nome.names.append(name!)
//print("all names:", nome.names)
// print("not duplicate")
numsadded += 1
let lat = (item.sourceInfo?.geoLocation?.geogLocation?.latitude)
let long = (item.sourceInfo?.geoLocation?.geogLocation?.longitude)
completion(lat!, long!, name!)
}
}
}
Api.order = 1
print("order is now 1")
return
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
print("done with urlsession")
}
}
However this code crashes when handling any more than a few JSON files/API requests, giving me the error Thread 10: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
at the line let posts = try! JSONDecoder().decode(Post.self, from: data)
As it stands right now in SwiftUI how would I go about doing this?