Files
multica/apps/ios/Multica/Models/TaskMessage.swift
Jiayuan 31c2476a7b feat(ios): add MVP iOS app with issue management and agent log viewing
SwiftUI app (iOS 17+) with zero third-party dependencies:
- Passwordless email authentication with Keychain token storage
- Workspace selection and multi-workspace support
- Issue list grouped by status with search and filtering
- Issue detail with inline status/priority/assignee editing
- Comments with threaded display and compose
- Agent task runs history and real-time execution log streaming
- WebSocket integration for live updates
2026-04-02 23:50:28 +08:00

72 lines
2.0 KiB
Swift

import Foundation
struct TaskMessage: Codable, Identifiable, Sendable {
let taskId: String
let issueId: String?
let seq: Int
let type: MessageType
let tool: String?
let content: String?
let input: [String: AnyCodable]?
let output: String?
var id: String { "\(taskId)-\(seq)" }
enum CodingKeys: String, CodingKey {
case seq, type, tool, content, input, output
case taskId = "task_id"
case issueId = "issue_id"
}
}
enum MessageType: String, Codable, Sendable {
case text
case thinking
case toolUse = "tool_use"
case toolResult = "tool_result"
case error
}
// Simple wrapper for heterogeneous JSON values
struct AnyCodable: Codable, @unchecked Sendable {
let value: Any
init(_ value: Any) {
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let string = try? container.decode(String.self) {
value = string
} else if let int = try? container.decode(Int.self) {
value = int
} else if let double = try? container.decode(Double.self) {
value = double
} else if let bool = try? container.decode(Bool.self) {
value = bool
} else if let dict = try? container.decode([String: AnyCodable].self) {
value = dict.mapValues(\.value)
} else if let array = try? container.decode([AnyCodable].self) {
value = array.map(\.value)
} else {
value = NSNull()
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
if let string = value as? String {
try container.encode(string)
} else if let int = value as? Int {
try container.encode(int)
} else if let double = value as? Double {
try container.encode(double)
} else if let bool = value as? Bool {
try container.encode(bool)
} else {
try container.encodeNil()
}
}
}