mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
commit
1dcded700d
3 changed files with 8 additions and 168 deletions
|
|
@ -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 = "<group>"; };
|
||||
B399E8A32B6F486400E4488E /* RetryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetryButton.swift; sourceTree = "<group>"; };
|
||||
B3E905B02B71F7F300654D07 /* TextMessageField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageField.swift; sourceTree = "<group>"; };
|
||||
C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMBTileOverlay.swift; sourceTree = "<group>"; };
|
||||
D93068D22B8129510066FBC8 /* MessageContextMenuItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageContextMenuItems.swift; sourceTree = "<group>"; };
|
||||
D93068D42B812B700066FBC8 /* MessageDestination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDestination.swift; sourceTree = "<group>"; };
|
||||
D93068D62B8146690066FBC8 /* MessageText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageText.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -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<String>(value: "name")
|
||||
let value = Expression<String>(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<SQLite.Blob>("tile_data")
|
||||
// let zoomLevel = Expression<Int64>("zoom_level")
|
||||
// let tileColumn = Expression<Int64>("tile_column")
|
||||
// let tileRow = Expression<Int64>("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)!
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
10
README.md
10
README.md
|
|
@ -1,9 +1,5 @@
|
|||
# Meshtastic Apple Clients
|
||||
|
||||
<a href="https://apple.co/3Auysep">
|
||||
<img alt="Meshtastic App Store Launch Image" src="meshtastic-1080x1080.png" />
|
||||
</a>
|
||||
|
||||
## 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue