ios – XML same item with different tags decoded into same bucket


This is the XML file I want to decode

<workout_file>
    <author>afaag</author>
    <name>afa</name>
    <description>ag326 wges</description>
    <sportType>bike</sportType>
    <tags>
    </tags>
    <workout>
        <Warmup Duration="600" PowerLow="0.25" PowerHigh="0.75"/>
        <Cooldown Duration="600" PowerLow="0.75" PowerHigh="0.25"/>
    </workout>
</workout_file>

This is the code which I’m currently using to decode the XML. I initially thought that the code will properly differentiate between the XMLs based on the tags <Warmup> <Cooldown> etc but it seems like it’s using the attributes within the tags.

Is there something that can be done to properly decode it based on the tags? Note that I am using XMLCoder

struct Workout: Codable {
  let workout: [WorkoutSegment]
  
  enum CodingKeys: String, CodingKey {
    case workout = "workout"
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    var workoutSegments = [WorkoutSegment]()
    var workoutContainer = try container.nestedUnkeyedContainer(forKey: .workout)
    
    while !workoutContainer.isAtEnd {

     if let warmUp = try? workoutContainer.decode(WarmUp.self) {
        print("decoding WarmUp")
        workoutSegments.append(WorkoutSegment(warmUp: warmUp))
      } else if let coolDown = try? workoutContainer.decode(CoolDown.self) {
        print("decoding CoolDown")
        workoutSegments.append(WorkoutSegment(coolDown: coolDown))
      } else {
        // If the next element cannot be decoded, exit the loop
        print("=== oops ===")
        break
      }
    }
    
    self.workout = workoutSegments
  }
}


struct WorkoutSegment: Codable {
  let warmUp: WarmUp?
  let coolDown: CoolDown?
  
  enum CodingKeys: String, CodingKey {
    case warmUp = "Warmup"
    case coolDown = "Cooldown"
  }
  
  init(warmUp: WarmUp? = nil, coolDown: CoolDown? = nil) {
    self.warmUp = warmUp
    self.coolDown = coolDown
  }
}


// <Warmup Duration="300" PowerLow="0.42449999" PowerHigh="0.70449996" />
struct WarmUp: Codable {
  let duration: Double
  let powerLow: Double
  let powerHigh: Double
  let textevent: [TextEvent]?
  
  enum CodingKeys: String, CodingKey {
    case duration = "Duration"
    case powerLow = "PowerLow"
    case powerHigh = "PowerHigh"
    case textevent = "textevent"
  }
}

struct CoolDown: Codable {
  let duration: Double
  let powerLow: Double
  let powerHigh: Double
  let textevent: [TextEvent]?
  
  enum CodingKeys: String, CodingKey {
    case duration = "Duration"
    case powerLow = "PowerLow"
    case powerHigh = "PowerHigh"
    case textevent = "textevent"
  }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img