1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//
// ADSBDataSource.swift
// LearnMapKit
//
// Created for MVVM refactoring
//
import Foundation
import Combine
// MARK: - Data Source Protocol
protocol ADSBDataSource: AnyObject {
var dataStream: AnyPublisher<ADSBDataEvent, Never> { get }
var connectionState: AnyPublisher<DataSourceState, Never> { get }
var configuration: DataSourceConfiguration { get }
func configure(with config: DataSourceConfiguration) async
func start() async throws
func stop() async
func reconnect() async throws
}
// MARK: - Data Events
enum ADSBDataEvent {
case aircraftIdentification(address: Int, icaoName: String)
case aircraftPosition(address: Int, latitude: Double, longitude: Double)
case aircraftAltitude(address: Int, altitude: Int)
case rawMessage(String)
case error(Error)
}
// MARK: - Data Source State
enum DataSourceState: Equatable {
case idle
case configuring
case connecting
case connected
case disconnected
case error(String)
static func == (lhs: DataSourceState, rhs: DataSourceState) -> Bool {
switch (lhs, rhs) {
case (.idle, .idle), (.configuring, .configuring),
(.connecting, .connecting), (.connected, .connected),
(.disconnected, .disconnected):
return true
case let (.error(lhsError), .error(rhsError)):
return lhsError == rhsError
default:
return false
}
}
}
// MARK: - Configuration
protocol DataSourceConfiguration {
var sourceType: DataSourceType { get }
}
enum DataSourceType {
case file(path: String)
case network(host: String, port: Int)
case test(mockData: [String])
}
struct FileDataSourceConfiguration: DataSourceConfiguration {
let sourceType: DataSourceType
let filePath: String
let processRate: Int // messages per second
init(filePath: String, processRate: Int = 120) {
self.filePath = filePath
self.processRate = processRate
self.sourceType = .file(path: filePath)
}
}
struct NetworkDataSourceConfiguration: DataSourceConfiguration {
let sourceType: DataSourceType
let hostname: String
let port: Int
let reconnectAttempts: Int
let timeoutInterval: TimeInterval
init(hostname: String, port: Int, reconnectAttempts: Int = 3, timeoutInterval: TimeInterval = 10.0) {
self.hostname = hostname
self.port = port
self.reconnectAttempts = reconnectAttempts
self.timeoutInterval = timeoutInterval
self.sourceType = .network(host: hostname, port: port)
}
}
|