import Foundation enum StanzaType { enum IqType: String { case get case set case result case error } enum MessageType: String { case chat case groupchat case headline case normal case error case none } enum PresenceType: String { case subscribe case unsubscribe case subscribed case unsubscribed } case iq(IqType) case message(MessageType) case presense(PresenceType) // Should never appear case unknown } struct Stanza { let wrapped: XMLElement init?(wrap: XMLElement) { guard ["iq", "message", "presence"].contains(wrap.name) else { return nil } wrapped = wrap } var type: StanzaType { switch wrapped.name { case "iq": if let type = StanzaType.IqType(rawValue: wrapped.attributes["type"] ?? "") { return .iq(type) } else { warn() return .unknown } case "message": let type = StanzaType.MessageType(rawValue: wrapped.attributes["type"] ?? "none") ?? .none return .message(type) case "presence": if let type = StanzaType.PresenceType(rawValue: wrapped.attributes["type"] ?? "") { return .presense(type) } else { warn() return .unknown } default: warn() return .unknown } } var id: String? { wrapped.attributes["id"] } } // MARK: Init extension Stanza { static func iqGet(payload: XMLElement) -> Stanza? { let req = XMLElement( name: "iq", xmlns: nil, attributes: ["type": "get", "id": XMLElement.randomId], content: nil, nodes: [payload] ) return Stanza(wrap: req) } static func iqSet(payload: XMLElement) -> Stanza? { let req = XMLElement( name: "iq", xmlns: nil, attributes: ["type": "set", "id": XMLElement.randomId], content: nil, nodes: [payload] ) return Stanza(wrap: req) } } private extension Stanza { func warn() { print("Something went wrong! with \(wrapped.stringRepresentation.prettyStr)") } }