'JSONDecoder but sometimes the key is missing, how to replace data - Swift

I'm trying to decode a JSON result in Swift but sometimes one of the keys is missing in the JSON which is causing my attempt at decoding to crash. I cannot figure out a way to replace a missing key with a value to prevent it from crashing and to keep my data structured and in line with other arrays and their positions.

It works perfectly unless there is a missing key from the API, in which case I'm getting a crash.

Here is my code:

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

struct PortHW: Codable {
    let EventType: String
    let DateTime: String
    let Height: Double
}

func getPortHW(portID: String) -> (eventArray: [String], timeArray: [String], heightArray: [Double]) {
    
    var json: Data? = nil
    
    let semaphore = DispatchSemaphore (value: 0)
  
    var request = URLRequest(url: URL(string: "https://admiraltyapi.azure-api.net/uktidalapi/api/V1/Stations/\(portID)/TidalEvents?duration=7")!,timeoutInterval: Double.infinity)
    request.addValue("HIDDEN", forHTTPHeaderField: "Ocp-Apim-Subscription-Key")
    
    request.httpMethod = "GET"
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data else {
            print(String(describing: error))
            semaphore.signal()
            return
        }
        
        json = data
        semaphore.signal()
    }
    
    task.resume()
    semaphore.wait()
     
    let decoder = JSONDecoder()
    let tideResult = try? decoder.decode([PortHW].self, from: json!)
    
    var eventArray: [String] = []
    var timeArray: [String] = []
    var heightArray: [Double] = []

    for item in tideResult! {
        eventArray.append(item.EventType)
        timeArray.append(item.DateTime)
        heightArray.append(item.Height)
    }
    
    return (eventArray, timeArray, heightArray)
}

The JSON I'm getting my data from looks like this most of the time:

[
    {
        "EventType": "HighWater",
        "DateTime": "2022-03-15T01:29:00",
        "IsApproximateTime": false,
        "Height": 4.2845989326570688,
        "IsApproximateHeight": false,
        "Filtered": false,
        "Date": "2022-03-15T00:00:00"
    },

But sometimes the key Height is missing, not empty, but missing... I've struggled with finding a way to replace the missing key with a value of 0.0 when it's not there.. I'd really appreciate some guidance.

Thank you.



Solution 1:[1]

whichever is missing, you can make it optional

like this:

struct PortHW: Codable {
    let EventType: String
    let DateTime: String
    let Height: Double?
}
extension PortHW {

     func getHeight() -> Double {
        if let height = self.Height {
            return height
        }
        return 0.0
   }

}

or you can just add defaultValue ==> 0.0

   for item in tideResult! {
        eventArray.append(item.EventType)
        timeArray.append(item.DateTime)
        heightArray.append(item.Height ?? 0.0)
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Oguzhan Karakus