72 lines
2.1 KiB
Swift
72 lines
2.1 KiB
Swift
import Foundation
|
|
import WidgetKit
|
|
import SwiftUI
|
|
|
|
let operationInfoSnapshotURL = "https://jr-shikoku-api-data-storage.haruk.in/operation-info/jr-shikoku/latest.json"
|
|
let delayInfoLegacyURL = "https://jr-shikoku-api-data-storage.haruk.in/legacy/trainfo-ex.txt"
|
|
|
|
/// App Group ID shared between the main app and widget extension.
|
|
let appGroupID = "group.jrshikokuinfo.xprocess.hrkn"
|
|
|
|
// MARK: - Shared data helpers
|
|
|
|
struct FelicaSnapshot: Codable {
|
|
let balance: Int
|
|
let idm: String
|
|
let systemCode: String?
|
|
let scannedAt: String
|
|
}
|
|
|
|
struct OperationInfoCompatibility: Decodable {
|
|
let operationInfoText: String
|
|
let hasOperationInfo: Bool
|
|
}
|
|
|
|
struct OperationInfoSnapshot: Decodable {
|
|
let compatibility: OperationInfoCompatibility
|
|
}
|
|
|
|
enum OperationInfoFetchError: Error {
|
|
case invalidURL
|
|
case invalidResponse
|
|
}
|
|
|
|
func fetchOperationInfoSnapshot(completion: @escaping (Result<OperationInfoSnapshot, Error>) -> Void) {
|
|
guard let url = URL(string: operationInfoSnapshotURL) else {
|
|
completion(.failure(OperationInfoFetchError.invalidURL))
|
|
return
|
|
}
|
|
|
|
var request = URLRequest(
|
|
url: url,
|
|
cachePolicy: .reloadIgnoringLocalCacheData,
|
|
timeoutInterval: 15
|
|
)
|
|
request.setValue("no-cache", forHTTPHeaderField: "Cache-Control")
|
|
|
|
URLSession.shared.dataTask(with: request) { data, response, error in
|
|
guard error == nil,
|
|
let response = response as? HTTPURLResponse,
|
|
(200..<300).contains(response.statusCode),
|
|
let data = data else {
|
|
completion(.failure(error ?? OperationInfoFetchError.invalidResponse))
|
|
return
|
|
}
|
|
|
|
do {
|
|
completion(.success(try JSONDecoder().decode(OperationInfoSnapshot.self, from: data)))
|
|
} catch {
|
|
completion(.failure(error))
|
|
}
|
|
}.resume()
|
|
}
|
|
|
|
func sharedDefaults() -> UserDefaults {
|
|
UserDefaults(suiteName: appGroupID) ?? .standard
|
|
}
|
|
|
|
func loadFelicaSnapshot() -> FelicaSnapshot? {
|
|
guard let data = sharedDefaults().data(forKey: "felicaLastSnapshot") else { return nil }
|
|
return try? JSONDecoder().decode(FelicaSnapshot.self, from: data)
|
|
}
|