aaffa3771c
Two-target restructure: shared sources (models, services, settings, extensions, team logos) move into Shared/, consumed by both the existing macOS menu bar app and a new iOS app. MainService no longer imports AppKit — platform code attaches via a MainServiceObserver protocol (MacObserverAdapter wires back to MenuManager / StatusItemManager / NotificationManager). iPhone app is a single SwiftUI page mirroring the macOS menu (playoff round + yesterday/today/tomorrow), with a gear-icon settings sheet (display option + IndieAbout for license/changelog). Persistent JSON snapshot in Application Support paints last-known data on cold launch; "Updated …" header escalates secondary → orange (>5min) → red (>30min) so staleness is visually unmistakable. Foreground polling, scenePhase refresh, and pull-to-refresh; no notifications on iOS in v1.
43 lines
1.2 KiB
Swift
43 lines
1.2 KiB
Swift
//
|
|
// ApiService.swift
|
|
// IceGlass
|
|
//
|
|
// Copyright 2026 Rouslan Zenetl. All Rights Reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
typealias ApiServiceCallback = (_ jsonData: Data, _ response: URLResponse) -> Void
|
|
|
|
class ApiService: @unchecked Sendable {
|
|
private let logger = IceGlassLogger(
|
|
subsystem: Bundle.main.bundleIdentifier ?? "dev.rzen.indie.IceGlass",
|
|
category: "ApiService"
|
|
)
|
|
|
|
let url: URL
|
|
let callback: ApiServiceCallback
|
|
|
|
var previousFetchTime: Date = .distantPast
|
|
|
|
init(url: URL?, callback: @escaping ApiServiceCallback) {
|
|
guard let url = url else {
|
|
preconditionFailure("ApiService initialised with nil URL — caller bug.")
|
|
}
|
|
self.url = url
|
|
self.callback = callback
|
|
}
|
|
|
|
func fetch() async {
|
|
do {
|
|
let (data, response) = try await URLSession.shared.data(from: url)
|
|
logger.info("Polling: \(self.url)")
|
|
logger.debug("Previous: \(Date.now.timeIntervalSince(previousFetchTime).humanReadableTime())")
|
|
previousFetchTime = Date.now
|
|
callback(data, response)
|
|
} catch {
|
|
logger.error("Invalid response from \(self.url) \(error)")
|
|
}
|
|
}
|
|
}
|