2022-06-12 01:25:42 -07:00
|
|
|
|
// Copyright (C) 2022 Garth Vander Houwen
|
|
|
|
|
|
|
2021-08-18 22:33:05 -07:00
|
|
|
|
import SwiftUI
|
2021-11-28 17:03:03 -08:00
|
|
|
|
import CoreData
|
2021-08-18 22:33:05 -07:00
|
|
|
|
|
|
|
|
|
|
@main
|
2022-06-09 21:58:22 -07:00
|
|
|
|
struct MeshtasticAppleApp: App {
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2021-12-12 17:17:46 -08:00
|
|
|
|
let persistenceController = PersistenceController.shared
|
2022-12-04 00:28:26 -08:00
|
|
|
|
@ObservedObject private var bleManager: BLEManager = BLEManager()
|
2022-11-11 19:21:52 -08:00
|
|
|
|
@Environment(\.scenePhase) var scenePhase
|
2021-11-29 21:11:27 -08:00
|
|
|
|
|
2022-10-09 18:32:21 -07:00
|
|
|
|
@State var saveChannels = false
|
|
|
|
|
|
@State var incomingUrl: URL?
|
2022-10-10 15:02:27 -07:00
|
|
|
|
@State var channelSettings: String?
|
2021-11-29 21:11:27 -08:00
|
|
|
|
|
2021-08-18 22:33:05 -07:00
|
|
|
|
var body: some Scene {
|
|
|
|
|
|
WindowGroup {
|
2021-10-24 01:26:04 -07:00
|
|
|
|
ContentView()
|
2021-12-12 17:17:46 -08:00
|
|
|
|
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
2021-11-28 17:03:03 -08:00
|
|
|
|
.environmentObject(bleManager)
|
2022-10-12 15:26:25 -07:00
|
|
|
|
.sheet(isPresented: $saveChannels) {
|
2022-10-18 20:25:11 -07:00
|
|
|
|
SaveChannelQRCode(channelSetLink: channelSettings ?? "Empty Channel URL", bleManager: bleManager)
|
2022-10-12 15:26:25 -07:00
|
|
|
|
.presentationDetents([.medium, .large])
|
|
|
|
|
|
.presentationDragIndicator(.visible)
|
|
|
|
|
|
}
|
2022-06-28 20:20:02 -07:00
|
|
|
|
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
|
2022-06-29 20:04:20 -07:00
|
|
|
|
|
2022-10-09 18:32:21 -07:00
|
|
|
|
print("URL received \(userActivity)")
|
2022-11-17 21:44:07 -08:00
|
|
|
|
self.incomingUrl = userActivity.webpageURL
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
|
|
|
|
|
if (self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/e/#")) != nil {
|
|
|
|
|
|
|
2022-11-17 21:44:07 -08:00
|
|
|
|
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
|
|
|
|
|
|
self.channelSettings = components.last!
|
2022-10-10 15:02:27 -07:00
|
|
|
|
}
|
2022-11-17 21:44:07 -08:00
|
|
|
|
self.saveChannels = true
|
|
|
|
|
|
print("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")")
|
2022-10-09 18:32:21 -07:00
|
|
|
|
}
|
2022-11-17 21:44:07 -08:00
|
|
|
|
if self.saveChannels {
|
|
|
|
|
|
print("User wants to open Channel Settings URL: \(String(describing: self.incomingUrl!.relativeString))")
|
2022-07-14 07:14:43 -07:00
|
|
|
|
}
|
2022-06-28 20:20:02 -07:00
|
|
|
|
}
|
2022-06-28 06:56:50 -07:00
|
|
|
|
.onOpenURL(perform: { (url) in
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2022-10-07 07:31:17 -07:00
|
|
|
|
print("Some sort of URL was received \(url)")
|
2022-11-17 21:44:07 -08:00
|
|
|
|
self.incomingUrl = url
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2022-10-10 15:02:27 -07:00
|
|
|
|
if url.absoluteString.lowercased().contains("meshtastic.org/e/#") {
|
2022-11-17 21:44:07 -08:00
|
|
|
|
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
|
|
|
|
|
|
self.channelSettings = components.last!
|
2022-10-10 15:02:27 -07:00
|
|
|
|
}
|
2022-11-17 21:44:07 -08:00
|
|
|
|
self.saveChannels = true
|
|
|
|
|
|
print("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")")
|
2022-10-07 07:31:17 -07:00
|
|
|
|
} else {
|
2022-10-10 21:21:58 -07:00
|
|
|
|
saveChannels = false
|
2022-11-17 21:44:07 -08:00
|
|
|
|
print("User wants to import a MBTILES offline map file: \(self.incomingUrl?.absoluteString ?? "No Tiles link")")
|
2022-08-03 16:56:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-06 10:33:18 -08:00
|
|
|
|
// we are expecting a .mbtiles map file that contains raster data
|
|
|
|
|
|
// save it to the documents directory, and name it offline_map.mbtiles
|
2022-01-22 15:23:09 +13:00
|
|
|
|
let fileManager = FileManager.default
|
|
|
|
|
|
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
|
|
|
|
let destination = documentsDirectory.appendingPathComponent("offline_map.mbtiles", isDirectory: false)
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2022-11-17 21:44:07 -08:00
|
|
|
|
if !self.saveChannels {
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
|
|
|
|
|
// tell the system we want the file please
|
2022-12-15 06:16:07 +13:00
|
|
|
|
guard url.startAccessingSecurityScopedResource() else {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
|
|
|
|
|
// do we need to delete an old one?
|
|
|
|
|
|
if fileManager.fileExists(atPath: destination.path) {
|
2022-10-10 21:21:58 -07:00
|
|
|
|
print("ℹ️ Found an old map file. Deleting it")
|
|
|
|
|
|
try? fileManager.removeItem(atPath: destination.path)
|
|
|
|
|
|
}
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2022-10-10 21:21:58 -07:00
|
|
|
|
do {
|
|
|
|
|
|
try fileManager.copyItem(at: url, to: destination)
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
print("Copy MB Tile file failed. Error: \(error)")
|
|
|
|
|
|
}
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
|
|
|
|
|
if fileManager.fileExists(atPath: destination.path) {
|
2022-10-10 21:21:58 -07:00
|
|
|
|
print("ℹ️ Saved the map file")
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
|
|
|
|
|
// need to tell the map view that it needs to update and try loading the new overlay
|
2022-10-10 21:21:58 -07:00
|
|
|
|
UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "lastUpdatedLocalMapFile")
|
2023-03-06 10:33:18 -08:00
|
|
|
|
|
2022-10-10 21:21:58 -07:00
|
|
|
|
} else {
|
|
|
|
|
|
print("💥 Didn't save the map file")
|
|
|
|
|
|
}
|
2022-01-22 15:23:09 +13:00
|
|
|
|
}
|
2022-06-28 06:56:50 -07:00
|
|
|
|
})
|
2021-10-24 01:26:04 -07:00
|
|
|
|
}
|
2021-11-04 08:36:55 -07:00
|
|
|
|
.onChange(of: scenePhase) { (newScenePhase) in
|
|
|
|
|
|
switch newScenePhase {
|
|
|
|
|
|
case .background:
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("ℹ️ Scene is in the background")
|
2021-12-15 23:53:45 -08:00
|
|
|
|
do {
|
2021-12-25 23:48:12 -08:00
|
|
|
|
|
2021-12-15 23:53:45 -08:00
|
|
|
|
try persistenceController.container.viewContext.save()
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("💾 Saved CoreData ViewContext when the app went to the background.")
|
2021-12-25 23:48:12 -08:00
|
|
|
|
|
2021-12-15 23:53:45 -08:00
|
|
|
|
} catch {
|
2021-12-25 23:48:12 -08:00
|
|
|
|
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("💥 Failed to save viewContext when the app goes to the background.")
|
2021-12-15 23:53:45 -08:00
|
|
|
|
}
|
2021-11-04 08:36:55 -07:00
|
|
|
|
case .inactive:
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("ℹ️ Scene is inactive")
|
2021-11-04 08:36:55 -07:00
|
|
|
|
case .active:
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("ℹ️ Scene is active")
|
2021-11-04 08:36:55 -07:00
|
|
|
|
@unknown default:
|
2021-12-24 21:50:10 -08:00
|
|
|
|
print("💥 Apple must have changed something")
|
2021-11-04 08:36:55 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-08-18 22:33:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|