Files
fantasy-watch/FantasyWatch/Shared/Networking/YahooAPI/XMLResponseDecoder.swift
Michael Simard 1ade3b39ff Initial implementation of Fantasy Hockey watchOS app
Implemented complete TCA architecture for iOS and watchOS targets:
- Authentication flow (Sign in with Apple + Yahoo OAuth)
- OAuth token management with iCloud Key-Value Storage
- Yahoo Fantasy Sports API client with async/await
- Watch Connectivity for iPhone ↔ Watch data sync
- Complete UI for both iPhone and Watch platforms

Core features:
- Matchup score display
- Category breakdown with win/loss/tie indicators
- Roster status tracking
- Manual refresh functionality
- Persistent data caching on Watch

Technical stack:
- The Composable Architecture for state management
- Swift Concurrency (async/await, actors)
- WatchConnectivity framework
- Sign in with Apple
- OAuth 2.0 authentication flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 00:40:31 -06:00

62 lines
2.1 KiB
Swift

//
// XMLResponseDecoder.swift
// FantasyWatch
//
// Created by Claude Code
//
import Foundation
final class XMLResponseDecoder: NSObject, XMLParserDelegate {
private var currentElement = ""
private var currentValue = ""
private var elementStack: [String] = []
private var dataDict: [String: Any] = [:]
private var arrayStack: [[String: Any]] = []
func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T {
let parser = XMLParser(data: data)
parser.delegate = self
guard parser.parse() else {
throw NetworkError.decodingError(
NSError(domain: "XMLDecoder", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to parse XML"])
)
}
let jsonData = try JSONSerialization.data(withJSONObject: dataDict)
return try JSONDecoder().decode(T.self, from: jsonData)
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElement = elementName
elementStack.append(elementName)
currentValue = ""
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
currentValue += string.trimmingCharacters(in: .whitespacesAndNewlines)
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
elementStack.removeLast()
if !currentValue.isEmpty {
let path = elementStack.joined(separator: ".")
dataDict[elementName] = currentValue
if !path.isEmpty {
dataDict[path + "." + elementName] = currentValue
}
}
currentValue = ""
}
}
// NOTE: This is a simplified XML decoder for POC purposes.
// The Yahoo Fantasy API returns complex nested XML structures.
// For production, we would need to implement more sophisticated parsing
// that handles arrays, nested objects, and the specific Yahoo XML schema.
// For now, we will parse the specific endpoints we need with custom logic.