diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 17b498b9..dca5ef1c 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -32,7 +32,6 @@ 6DEDA55C2A9592F900321D2E /* MessageEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */; }; B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B399E8A32B6F486400E4488E /* RetryButton.swift */; }; B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; }; - C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */; }; C9697FA527933B8C00250207 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = C9697FA427933B8C00250207 /* SQLite */; }; D93068D32B8129510066FBC8 /* MessageContextMenuItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93068D22B8129510066FBC8 /* MessageContextMenuItems.swift */; }; D93068D52B812B700066FBC8 /* MessageDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93068D42B812B700066FBC8 /* MessageDestination.swift */; }; @@ -261,7 +260,6 @@ 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageEntityExtension.swift; sourceTree = ""; }; B399E8A32B6F486400E4488E /* RetryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetryButton.swift; sourceTree = ""; }; B3E905B02B71F7F300654D07 /* TextMessageField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageField.swift; sourceTree = ""; }; - C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMBTileOverlay.swift; sourceTree = ""; }; D93068D22B8129510066FBC8 /* MessageContextMenuItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageContextMenuItems.swift; sourceTree = ""; }; D93068D42B812B700066FBC8 /* MessageDestination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDestination.swift; sourceTree = ""; }; D93068D62B8146690066FBC8 /* MessageText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageText.swift; sourceTree = ""; }; @@ -558,7 +556,6 @@ C9A7BC0E27759A6800760B50 /* Custom */ = { isa = PBXGroup; children = ( - C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */, DD964FC32974767D007C176F /* MapViewFitExtension.swift */, DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */, DDDB443529F6287000EE2349 /* MapButtons.swift */, @@ -1361,7 +1358,6 @@ DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */, DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */, DDAB580D2B0DAA9E00147258 /* Routes.swift in Sources */, - C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */, D93068D52B812B700066FBC8 /* MessageDestination.swift in Sources */, DDA9515E2BC6F56F00CEA535 /* IndoorAirQuality.swift in Sources */, DDDB444E29F8AB0E00EE2349 /* Int.swift in Sources */, @@ -1604,7 +1600,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1639,7 +1635,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1671,7 +1667,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1704,7 +1700,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic/Views/MapKitMap/Custom/LocalMBTileOverlay.swift b/Meshtastic/Views/MapKitMap/Custom/LocalMBTileOverlay.swift deleted file mode 100644 index f16d63e3..00000000 --- a/Meshtastic/Views/MapKitMap/Custom/LocalMBTileOverlay.swift +++ /dev/null @@ -1,154 +0,0 @@ -// -// LocalMBTileOverlay.swift -// MeshtasticApple -// -// Copyright(c) Joshua Pirihi 16/01/22. -// - -import UIKit -import MapKit -import SQLite -import OSLog - -extension MKMapRect { - init(coordinates: [CLLocationCoordinate2D]) { - self = MKMapRect() - var coordinates = coordinates - if !coordinates.isEmpty { - let first = coordinates.removeFirst() - var top = first.latitude - var bottom = first.latitude - var left = first.longitude - var right = first.longitude - coordinates.forEach { coordinate in - top = max(top, coordinate.latitude) - bottom = min(bottom, coordinate.latitude) - left = min(left, coordinate.longitude) - right = max(right, coordinate.longitude) - } - let topLeft = MKMapPoint(CLLocationCoordinate2D(latitude: top, longitude: left)) - let bottomRight = MKMapPoint(CLLocationCoordinate2D(latitude: bottom, longitude: right)) - self = MKMapRect(x: topLeft.x, y: topLeft.y, - width: bottomRight.x - topLeft.x, height: bottomRight.y - topLeft.y) - } - } -} - -enum MapTileError: Error { - case invalidFormat - case other -} - -class LocalMBTileOverlay: MKTileOverlay { - - var path: String! - var mb: Connection! - private var _boundingMapRect: MKMapRect! - override var boundingMapRect: MKMapRect { - return _boundingMapRect - } - - init?(mbTilePath path: String) { - - super.init(urlTemplate: nil) - self.path = path - do { - self.mb = try Connection(self.path, readonly: true) - let metadata = Table("metadata") - - let name = Expression(value: "name") - let value = Expression(value: "value") - - // make sure it's raster - let formatQuery = try mb.pluck(metadata.select(value).filter(name == "format")) - if formatQuery?[value] == nil || (formatQuery![value] != "jpeg" && formatQuery![value] != "jpg" && formatQuery![value] != "png") { - throw MapTileError.invalidFormat - } - - let minZQuery = try mb.pluck(metadata.select(value).filter(name == "minzoom")) - self.minimumZ = Int(minZQuery![value])! - - let maxZQuery = try mb.pluck(metadata.select(value).filter(name == "maxzoom")) - self.maximumZ = Int(maxZQuery![value])! - - self.isGeometryFlipped = true - - let boundingBoxString = try mb.pluck(metadata.select(value).filter(name == "bounds")) - let boundCoords = boundingBoxString![value].split(separator: ",") - let coords = [ - CLLocationCoordinate2D(latitude: Double(boundCoords[1]) ?? 0, - longitude: Double(boundCoords[0]) ?? 0), - CLLocationCoordinate2D(latitude: Double(boundCoords[3]) ?? 0, - longitude: Double(boundCoords[2]) ?? 0) - ] - self._boundingMapRect = MKMapRect(coordinates: coords) - - } catch { - Logger.services.error("Map tile error: \(error)") - return nil - } - } - -// override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) { -// -// let tileX = Int64(path.x) -// let tileY = Int64(path.y) -// let tileZ = Int64(path.z) -// let tileData = Expression("tile_data") -// let zoomLevel = Expression("zoom_level") -// let tileColumn = Expression("tile_column") -// let tileRow = Expression("tile_row") -// -// if let dataQuery = try? self.mb.pluck(Table("tiles").select(tileData).filter(zoomLevel == tileZ).filter(tileColumn == tileX).filter(tileRow == tileY)) { -// let data = Data(bytes: dataQuery[tileData].bytes, count: dataQuery[tileData].bytes.count)// dataQuery![tileData].bytes -// result(data, nil) -// } else { -// Logger.services.error("No tile here: x:\(tileX) y:\(tileY) z:\(tileZ)") -// let error = NSError(domain: "LocalMBTileOverlay", code: 1, userInfo: ["reason": "no_tile"]) -// result(nil, error) -// } -// } -} - -// public class CustomMapOverlaySource: MKTileOverlay { -// -// // requires folder: tiles/{mapName}/z/y/y,{tileType} -// private var parent: MapViewSwiftUI -// private let mapName: String -// private let tileType: String -// private let defaultTile: DefaultTile? -// -// public init( -// parent: MapViewSwiftUI, -// mapName: String, -// tileType: String, -// defaultTile: DefaultTile? -// ) { -// self.parent = parent -// self.mapName = mapName -// self.tileType = tileType -// self.defaultTile = defaultTile -// super.init(urlTemplate: "") -// } -// -// public override func url(forTilePath path: MKTileOverlayPath) -> URL { -// if let tileUrl = Bundle.main.url( -// forResource: "\(path.y)", -// withExtension: self.tileType, -// subdirectory: "tiles/\(self.mapName)/\(path.z)/\(path.x)", -// localization: nil -// ) { -// return tileUrl -// } else if let defaultTile = self.defaultTile, let defaultTileUrl = Bundle.main.url( -// forResource: defaultTile.tileName, -// withExtension: defaultTile.tileType, -// subdirectory: "tiles/\(self.mapName)", -// localization: nil -// ) { -// return defaultTileUrl -// } else { -// let urlstring = self.mapName+"\(path.z)/\(path.x)/\(path.y).png" -// return URL(string: urlstring)! -// } -// } -// } diff --git a/README.md b/README.md index a72c6ebb..de9af2a2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ # Meshtastic Apple Clients - - Meshtastic App Store Launch Image - - ## Overview SwiftUI client applications for iOS, iPadOS and macOS. @@ -28,8 +24,10 @@ open Meshtastic.xcworkspace ### Supported Operating Systems -* iOS 16+ -* iPadOS 16+ +The last two operating system versions are supported. Currently that is 16 and 17. + +* iOS 16.6+ +* iPadOS 16.6+ * macOS 13+ ### Code Standards