iOS-Entfernungen und Geofence-Grenzen auf einem Cloud-Mac testen

iOS-Entfernungen und Geofence-Grenzen auf einem Cloud-Mac testen

Wenn ein Geschäft in der Nähe plötzlich Zehntausende Kilometer entfernt angezeigt wird, muss nicht die Standortbestimmung ausgefallen sein. Vertauschte Breiten- und Längengrade, eine einfache Subtraktion über den 180. Längengrad hinweg oder das Runden einer Entfernung vor der Bereichsprüfung können ähnliche Fehler verursachen. Auf einem Cloud-Mac von GNUMac lässt sich zunächst die Berechnungslogik mit festen Koordinaten prüfen. Anschließend werden die Standortdaten und Geräte-Callbacks wieder angebunden. So lässt sich ein Fehler einer klaren Ursache zuordnen, statt die Karte immer wieder auf Verdacht zu verschieben.

Den Vertrag für Koordinaten und Entfernungen festlegen

Dieser Artikel prüft die Entfernung zwischen zwei Koordinaten auf der Erdoberfläche. Gemeint sind weder die Länge einer Fahrtroute noch die tatsächlich zu Fuß zurückgelegte Strecke. Die Eingabe erfolgt in Dezimalgrad, zuerst der Breitengrad, dann der Längengrad. Intern werden Entfernungen durchgehend in Metern verarbeitet; die Umrechnung erfolgt erst für die Anzeige.

Der Breitengrad muss zwischen −90 und +90 Grad liegen, der Längengrad zwischen −180 und +180 Grad. Nicht endliche Zahlenwerte müssen ebenfalls abgewiesen werden. Ungültige Eingaben dürfen nicht stillschweigend auf die Grenzwerte begrenzt werden. Andernfalls erscheinen beschädigte Daten aus vorgelagerten Systemen als scheinbar normale Datensätze.

Gültige Koordinaten sind noch keine verlässliche Standortbestimmung. Null Grad Breite und null Grad Länge bezeichnen einen gültigen Ort und dürfen nicht pauschal als „noch kein Standort ermittelt“ gelten. Ob dieser Wert akzeptiert wird, muss der Vertrag mit der Datenquelle festlegen.

Auch der auf dem Kartenbild sichtbare Abstand eignet sich nicht als erwarteter Wert. Projektion, Zoomstufe und Gerätepixel verändern die Darstellung, dürfen aber die Berechnung in der Geschäftslogik nicht beeinflussen.

Feste Testdaten auf dem Cloud-Mac ausführen

Bereiten Sie eine macOS-Umgebung vor, in der die gewünschte Entwickler-Toolchain bereits ausgewählt ist. Prüfen Sie mit xcrun swift --version, ob der Compiler verfügbar ist. Speichern Sie den folgenden Inhalt als distance-check.swift. Das Skript liest den aktuellen Standort nicht aus, benötigt keine Standortberechtigung und greift nicht auf das Netzwerk zu.

import Foundation
import CoreLocation

enum CoordinateError: Error {
    case invalid
}

func point(_ latitude: Double, _ longitude: Double) throws -> CLLocation {
    let coordinate = CLLocationCoordinate2D(
        latitude: latitude,
        longitude: longitude
    )
    guard latitude.isFinite,
          longitude.isFinite,
          CLLocationCoordinate2DIsValid(coordinate) else {
        throw CoordinateError.invalid
    }
    return CLLocation(latitude: latitude, longitude: longitude)
}

func rejects(_ latitude: Double, _ longitude: Double) -> Bool {
    do {
        _ = try point(latitude, longitude)
        return false
    } catch {
        return true
    }
}

let origin = try point(0, 0)
precondition(origin.distance(from: origin) == 0)

let east = try point(0, 179.9)
let west = try point(0, -179.9)
let crossing = east.distance(from: west)
precondition(crossing > 20_000 && crossing < 23_000)
precondition(abs(crossing - west.distance(from: east)) < 1)

let polarA = try point(89.9, 0)
let polarB = try point(89.9, 180)
let polarDistance = polarA.distance(from: polarB)
precondition(polarDistance > 20_000 && polarDistance < 23_000)

precondition(rejects(91, 0))
precondition(rejects(0, 181))
precondition(rejects(.nan, 0))
precondition(rejects(0, .infinity))

Führen Sie das Skript mit folgendem Befehl aus. Wenn alle Zusicherungen erfüllt sind, gibt es keine Ausgabe. Bei einem Fehler endet das Skript mit einem Status ungleich null und eignet sich damit direkt als Pipeline-Schritt.

xcrun swift distance-check.swift

Die angegebenen Bereiche sind großzügige Toleranzen für die Testdaten, keine gemessenen Leistungswerte und keine Zusage zur fachlichen Genauigkeit. Die Punkte auf beiden Seiten des 180. Längengrads liegen nahe beieinander. In Polnähe bedeutet auch eine große Längengraddifferenz nicht, dass die Punkte eine halbe Erdumrundung voneinander entfernt sind. Beide Fälle decken Fehler auf, die entstehen, wenn Breiten- und Längengrade wie ebene Koordinaten einfach voneinander abgezogen werden.

Die Geofence-Grenzprüfung als reine Funktion isolieren

Angenommen, die fachliche Regel lautet: „Eine Entfernung kleiner oder gleich dem Radius zählt als innerhalb.“ Prüfen Sie zunächst die Vergleichsfunktion mit vorgegebenen Entfernungen und binden Sie erst danach die berechneten Koordinatenabstände an. So müssen Sie nicht zwei Ebenen gleichzeitig debuggen. Hängen Sie den folgenden Code an dieselbe Datei an und führen Sie sie erneut aus.

func isInside(distance: Double, radius: Double) -> Bool {
    guard distance.isFinite, radius.isFinite,
          distance >= 0, radius >= 0 else {
        return false
    }
    return distance <= radius
}

precondition(isInside(distance: 499.9, radius: 500))
precondition(isInside(distance: 500, radius: 500))
precondition(!isInside(distance: 500.1, radius: 500))
precondition(!isInside(distance: .nan, radius: 500))
precondition(!isInside(distance: 0, radius: -1))

let meters = 1_250.0
precondition(meters / 1_000 == 1.25)

Grenztests müssen auch den Fall exakter Gleichheit abdecken, nicht nur eindeutig innerhalb oder außerhalb liegende Werte. Leiten Sie das Ergebnis nicht aus einer angezeigten Zeichenfolge wie „0,5 Kilometer“ ab. Unterschiedliche Ausgangsentfernungen können durch Rundung zur gleichen Anzeige führen.

Soll das Produkt häufige Zustandswechsel am Rand vermeiden, lässt sich eine Hysterese mit unterschiedlichen Schwellen für Eintritt und Austritt definieren. Das ist eine Zustandsmaschine und erfordert zusätzliche Tests mit aufeinanderfolgenden Eingaben. Eine beliebige Konstante für „ungefähr passend“ in die Vergleichsfunktion einzubauen, ist dafür kein Ersatz.

Standortgenauigkeit und Rechentoleranz trennen

Reale Standortmessungen enthalten zusätzlich einen Zeitstempel und eine horizontale Genauigkeit. Die Anbindungsschicht muss veraltete Messwerte ausdrücklich zurückweisen und negative Werte für die horizontale Genauigkeit behandeln. Auch gültige Koordinaten dürfen bei geringer Genauigkeit nicht unmittelbar ein Ereignis „Eintritt bestätigt“ auslösen.

Eine nachvollziehbare konservative Regel lautet: Die Entfernung sei d, die horizontale Genauigkeit a und der Radius r. Nur bei d+a≤r gilt der Standort als sicher innerhalb, nur bei d−a>r als sicher außerhalb. Alle übrigen Fälle werden als unbestimmt markiert. Das ist eine konservative fachliche Entscheidung, keine Interpretation des Genauigkeitswerts als garantierte absolute Fehlergrenze.

Speisen Sie beim Testen jeweils präzise, ungenaue, veraltete und ungültige Messwerte ein. Prüfen Sie, ob der unbestimmte Zustand erhalten bleibt und ob die Oberfläche fälschlicherweise ein eindeutiges Ergebnis anzeigt. Verdecken Sie das Rauschen der Standortmessung nicht durch großzügigere Zusicherungen für die Berechnung.

Nachweise sichern und die Logik ins iOS-Projekt integrieren

Das Skript eignet sich für eine schnelle Gegenprüfung des Framework-Verhaltens. Für die eigentliche Integration gehören Koordinatenvalidierung und Vergleichsfunktion in ein testbares Modul. Das Test-Target sollte die produktiv verwendete Implementierung direkt aufrufen. Pflegen Sie nur eine Fassung des Algorithmus, damit nicht das Skript korrekt arbeitet, während die App weiterhin alte Logik verwendet.

Halten Sie für jeden Lauf die Commit-Kennung, die Toolchain-Version, die Testkoordinaten, die ungerundeten Meterwerte und die fehlgeschlagenen Zusicherungen fest. Prüfen Sie nach einem Systemupdate zuerst, ob ein Fehler die Eingabevalidierung, den Entfernungsbereich oder die Zustandsregeln betrifft. Ersetzen Sie nicht pauschal alle erwarteten Werte.

Planen Sie abschließend eine Abnahme auf einem echten iOS-Gerät ein: Ereignisse der Regionsüberwachung, Hintergrundausführung und tatsächliche Bewegung gehören zu einer anderen Verarbeitungskette. Erfolgreiche reine Berechnungstests belegen nur, dass feste Eingaben vertragsgemäße Ergebnisse liefern. Diese Abgrenzung im Abnahmeprotokoll festzuhalten, ist wertvoller, als weitere zufällige Koordinaten hinzuzufügen.

Häufig gestellte Fragen

Validiert ein erfolgreicher Mac-Test das gesamte iOS-Geofencing?

Nein. Das Skript prüft Koordinaten, Distanzberechnung und Grenzwertregeln. Regionsereignisse, Hintergrundverhalten und tatsächliche Ortungsgenauigkeit müssen zusätzlich auf einem iOS-Gerät getestet werden.

Darf der angezeigte Kilometerwert über den Eintritt entscheiden?

Nein. Verwenden Sie den ungerundeten Meterwert für die Entscheidung. Einheitenumrechnung und Rundung gehören zur Anzeige; die Behandlung der Ortungsgenauigkeit braucht eigene Regeln.

Einen dedizierten Mac mini für Ihren Workflow konfigurieren

Wählen Sie Modell, Standort und Laufzeit passend zu Ihrem Projekt. Prüfen Sie zuerst Arbeitsspeicher, Speicherplatz und Verbindung. Der tatsächlich verfügbare Status wird Ihnen live in der Konsole angezeigt.

Legen Sie zuerst Ihren Workflow fest – und starten Sie dann den Mac.

Dedizierter physischer Mac mini. Wählen Sie Modell, Standort und Laufzeit und passen Sie den Speicherplatz anschließend an Ihr Projekt an.