tracelet_ios 3.3.2
tracelet_ios: ^3.3.2 copied to clipboard
iOS implementation of the Tracelet background geolocation plugin.
3.3.2 #
-
FIX (Location data, Android/iOS): Several location-map fields surfaced as static/default values in the Dart layer because the native-map → platform-channel converters dropped or mis-keyed them (#175):
getCurrentPosition(extras:, desiredAccuracy:)were silently ignored on Android (never forwarded to the SDK) — now applied.battery.isChargingwas alwaysfalse— the converter readisCharginginstead of the native snake_caseis_charging.isMovingwas alwaysfalse— readisMovinginstead of nativeis_moving.
Converters now read the native keys (with camelCase fallback), and field-by-field regression tests over the converters were added on both platforms to prevent recurrence.
-
TUNE (Crash detection): Lowered the default
crashGThresholdfrom3.0 gto2.0 g. Validation against the large VZCrash field dataset showed the 3.0 g speed-gated rule missed ~48% of real crashes (median impact ~2.2 g) while the false-positive budget was small. Crash detection is opt-in with a cancel-countdown, so the default now favours recall — raise it if you see too many prompts. See #173. (Crash detection remains beta pending first-party field validation.)
3.3.1 #
- CHORE: version bump for patch release
3.3.0 #
- FEAT (Driving & Safety): On-device driving-behavior telematics —
harsh_braking/harsh_acceleration/harsh_cornering/speedingviaTelematicsConfig+Tracelet.onDrivingEvent(opt-in, default off) (#163). - FEAT (Driving & Safety): On-device transport-mode classifier (still/walking/running/cycling/vehicle) fusing accelerometer + GPS via
ClassifierConfig+Tracelet.onModeChange(#164). - FEAT (Driving & Safety): Crash & fall detection with a cancel-countdown confirmation flow via
ImpactConfig+Tracelet.onImpactandTracelet.confirmImpact/Tracelet.cancelImpact(opt-in, default off) (#165). - All three features are default-off and side-channel — no change to existing tracking when disabled. See Driving & Safety.
3.2.19 #
CHORE: version bump for patch release
3.2.18 #
- FIX (Native):
ready()/getState()now populateState.configwith the active configuration instead of leaving it permanentlynull(#147). - FEAT: Add
HttpConfig.syncIntervalfor interval-based sync — the documented repeating-timer cadence was missing from the Dart config and the Pigeon layer; the native interval timer now flushes the offline queue on this cadence (#149). - FIX (Native):
destroySyncedLocations()returns the real number of synced-and-pruned locations instead of a hardcoded0stub (#154). - FEAT: Expose the offline queue with
getPendingLocations()andgetPendingLocationCount()(#159). - FIX (Native): Honor the
useKalmanFilterconfig key so the Extended Kalman Filter is no longer silently disabled by a key mismatch (#148). - FIX (Native): Propagate the detected activity (walking / driving / still) into recorded locations — fixes a permanent
"activity": "unknown"(#155). - FIX (Native): Rebuild the native location processor when
ready()applies a new config, so settings such asdistanceFiltertake effect immediately instead of using stale defaults (#157). - FIX (Native):
getCount()honors time-bound queries instead of always returning the whole-database total (#152). - FIX: Guard the
AuditConfighash-algorithm mapping so configuringsha384/sha512no longer crashes with a fatalRangeErrorduringready()— unsupported variants fall back tosha256(#150). - FIX (Native): The HTTP sync payload now includes each point's motion state
is_moving(#151) and its triggerevent(location / motionchange / heartbeat / geofence) (#156) — both were previously omitted by the native sync record.
3.2.17 #
- FIX (Native): Resolve iOS auto-sync thread starvation by offloading synchronous HTTP requests to a background DispatchQueue to prevent blocking Swift Concurrency pools (#146).
- CHORE (Docs): Fix Nextra changelog rendering bug and improve auto-translation glossary script for internationalization.
3.2.16 #
- FIX (Native): Resolve Android/iOS getting stuck in the moving state and never transitioning back to stationary, which kept continuous GPS active and drained the battery. The accelerometer stillness sampler now stays active during the stop-timeout countdown and requires sustained motion — rather than a single noisy or stale sample — to abort it (#142).
- FIX (Native): Background and post-reboot location captures are persisted (and therefore synced) again. Headless tracking (killed-state relaunch / boot) never calls
ready(), so an internal readiness guard silently dropped every captured location before it reached the database, leaving auto-sync with nothing to upload. - FIX (Android): The foreground-service notification now reliably appears when the app is backgrounded or terminated with
showNotificationOnPauseOnlyenabled. The app's own foreground service skewed foreground/background detection (and OS process-importance updates lag), so the pause-only notification was suppressed even though tracking and syncing continued.
3.2.15 #
- FIX (Native): Allow
getState()andstop()to be called beforeready()is invoked, correctly reporting persistent state and shutting down background services if the app was restarted from a killed state. - CHORE: Update dependencies and constraints.
- FIX: Resolve
MissingPluginExceptionand test timing issues withsetHasCustomSyncBodyBuilder.
3.2.14 #
3.2.13 #
- CHORE: Version bump to 3.2.13 to stay in lockstep with the federated set (Android
startOnBootreboot-tracking fix — seetracelet_android). No changes to this package.
3.2.12 #
- CHORE: Re-release to align the full federated package set and native SDKs to a single consistent version. The 3.2.11 release published with mismatched versions across some packages (a few resolved to 3.2.10). No functional code changes.
3.2.11 #
- FIX(ios): Fall back to the headless engine when a custom sync-body round-trip times out, instead of aborting the sync. Fixes location sync stopping after a few minutes while the app is backgrounded (Issue #134).
3.2.10 #
- FIX: ensure geofence action (ENTER/EXIT/DWELL) is correctly parsed from nested payloads on all platforms and update CI to scan dynamic frameworks for symbols.
3.2.9 #
- FIX(ios): Remove
TraceletCore+Dummy.swift/TraceletSyncFFI+Dummy.swift—@_silgen_namedeclarations from the old static library model caused "Undefined symbol" linker errors after the static→dynamic xcframework migration. - FIX(android): Catch
ForegroundServiceStartNotAllowedExceptioninLocationService.start()so callingready()from the background on Android 12+ no longer crashes the host app; the foreground service start is deferred until the app returns to foreground.
3.2.8 #
- FIX: Persist geofence ENTER/EXIT events in offline queue and auto-sync to server — events were previously dispatched to the app but never stored in the local SQLite database (Issue #128).
- FIX: Structured event envelope (
event_type,event_payload) for geofence events round-trips correctly throughgetLocations()andinsertLocation(). - FIX(sync): Stop POSTing malformed error payloads on failed HTTP sync requests; fix iOS custom-body deadlock in
setSyncBodyBuilder(Issue #125). - FIX(android): Throw
NOT_READYerror beforeready()is called to match iOS parity; previously Android silently ignored SDK calls before initialization (Issue #129). - FIX(ios): Resolve
flutter_rust_bridge has not been initializedon release builds —TraceletCoreis now a dynamic framework, preventing dead-code stripping of FRB symbols (Issues #116, #123, #124). - FIX(android): Resolve
Failed to lookup symbol 'frb_get_rust_content_hash'— Rust symbols are now loaded directly fromlibtracelet_core.sobypassingRTLD_LOCALisolation (Issues #116, #123). - PERF(ios): Reduce background motion sensor CPU/battery usage — accelerometer polling is now paused when stationary (Issue #130).
- FIX: Persist historical
is_movingstate per location record sogetLocations()returns accurate values instead of always returning the current live state (Issue #126).
3.2.7 #
- FIX(ios): prevent dead code stripping of flutter_rust_bridge symbols in release builds.
- FIX(android): implement OEM hardening mitigations and introduce
showPowerManagerto handle aggressive battery restrictions on specific OEM devices.
3.2.6 #
- PERF: Optimize database timestamp queries for O(log N) fast filtering and resolve precision bugs (Issue #119).
- FEAT: Implement
sslPinningFingerprintsnatively across iOS and Android with Rust configs. - FIX: Include pinned fingerprints in SSL verification error logs and messages.
- FIX: Rate limit Android MotionDetector logcat flooding during stillness (Issue #121).
- FIX: Resolve race conditions in tests for Issue 118.
- REFACTOR: Update integration test to use Config.fromMap for comprehensive Tracelet configuration testing.
3.2.5 #
- FIX: Resolved iOS accelerometer sensitivity mismatch (stationary lock) by normalizing incoming m/s² thresholds to g-force expected by CMMotionManager.
- FIX: Unify motion detection initial state and resume behavior across Android and iOS, preventing incorrect forced states on app launch and correctly resuming saved states.
- FIX: Resolved
flutter_rust_bridgedynamic library load failures on release builds for users withoutuse_frameworks!by preserving global symbols during Xcode stripping.
3.2.4 #
- FIX(ios): safely resolve dynamic symbols when
use_frameworks! :linkage => :dynamicis used.
3.2.3 #
- FIX: Force speed motion manager to evaluate initial speed on Android to prevent the state machine from being permanently stuck in
MOVINGwhen indoors (#115). - FIX: Resolve
flutter_rust_bridge has not been initializedcrash by ensuring the Rust core is instantiated and initialized before accessing methods (#116). - CHORE: Sync release versions across all packages.
3.2.2 #
- CHORE: Sync release versions across all federated packages and update Swift Package Manager configuration.
3.2.1 #
- CHORE: Align federated package versions and include additional patch updates.
3.2.0 #
- FEAT(ios): Add reverse geocoding functionality.
3.1.14 #
- FIX(ios): prevent dead code stripping of flutter_rust_bridge symbols in SPM apps by referencing them explicitly in TraceletIosPlugin
3.1.10 #
- FIX(ios): prevent dead code stripping of flutter_rust_bridge symbols in iOS release builds by setting DEAD_CODE_STRIPPING=NO in CocoaPods xcconfig.
3.1.9 #
- FIX(android): conditionally apply kotlin-android plugin to support older flutter SDKs while preventing warnings in modern Flutter environments.
- CHORE(ci): add strict pre-publish flutter build verification step to
release.yml.
3.1.8 #
- Fix iOS SPM publishing
3.1.7 #
- FIX(android): apply kotlin-android plugin to fix gradle build errors on newer AGP versions.
- FIX(ios): fix SPM source folder paths in release bundling to ensure SDK compiles properly via CocoaPods.
- FIX(ios): fix duplicate module import errors by adding conditional import checks for TraceletSDK.
3.1.4 #
- CHORE: Sync release versions across workspace.
3.0.1 #
- FIX(ios): Add missing
FlutterFrameworkdependency to SPM plugin configuration to resolve compilation failures andPlatformExceptions.
3.0.0 #
- FEAT: Massive Architecture Rewrite — Core algorithms are now powered by a high-performance Rust Core using
flutter_rust_bridge. - FEAT: Smart Motion Mode — Introduced
MotionDetectionMode.smartpowered by the Rust battery budget engine. - FEAT: Migrated all platform event channels to use strongly-typed Pigeon bridges.
2.1.0 #
- FIX: resolve background tracking loops, location stream drops, and permission issues. (8abc7d41)
- FIX: refactor string comparisons to enum indexing across all layers. (b591b246)
- FIX: refactor speed motion strings to typed enums across Flutter, Pigeon, Android, and iOS SDKs. (e974b728)
- FEAT(android): smart foreground notification visibility. (fbf46b27)
- FEAT: Speed-Based Motion Detection (#83). (5421e7a0)
2.0.8 #
- FIX(ios): Resolved type casting bug for 64-bit Pigeon
Int64integer values across all iOS config mappings. This ensures that integer configurations (such asstopTimeout) sent from Dart are correctly applied on iOS. - PERF(ios): Avoid overriding GPS
distanceFilterto continuous tracking duringstopTimeoutwhenpreventSuspendis active, significantly reducing stationary battery drain. - CHORE: Bump native
TraceletSDKdependency to2.0.8.
2.0.7 #
- FIX(interface): correct intToAuthStatus permission index mappings ([#80](https://github.com/Ikolvi/Tracelet/issues/80)). (8cfd7f51)
- CHORE: Update
tracelet_platform_interfaceconstraint to^2.0.7.
2.0.6 #
- CHORE: Update
tracelet_platform_interfaceconstraint to^2.0.6. - CHORE: Bump native
TraceletSDKdependency to2.0.6.
2.0.5 #
- CHORE: Version bump for monorepo consistency and package lockstep alignment.
- CHORE: Update
tracelet_platform_interfaceconstraint to^2.0.5. - CHORE: Bump native podspec version to
2.0.5.
2.0.4 #
- CHORE: Version bump for monorepo consistency and native SDK alignment.
- CHORE: Update
tracelet_platform_interfaceconstraint to^2.0.4.
2.0.3 #
- FIX: Removed unreliable timestamp drift heuristic from location spoofing detection.
2.0.1 #
- FIX: Fixed persistent blue location indicator by properly conditionally disabling
CLBackgroundActivitySessionandstartUpdatingLocation()in low-accuracy geofence-only mode. - CHORE: Bump native
TraceletSDKdependency to2.0.1.
2.0.0 #
- BREAKING: Migrated to Pigeon for all platform-to-native communication, providing a type-safe interface for host and flutter API calls.
- FIX: Resolved silent failures of native permission dialogs by ensuring all
CoreLocationandCoreMotionrequests are dispatched on the main thread. - FIX: Corrected
CLAuthorizationStatusmapping in the native bridge to ensure accurate permission status reporting to Flutter. - CHORE: Bump native
TraceletSDKdependency to2.0.0.
1.9.3 #
2:
3: - CHORE: Bump native TraceletSDK dependency to 1.1.4.
4:
5: ## 1.9.2
- CHORE: Constraint bump to
tracelet_platform_interface1.9.2. No iOS-side changes.
1.9.1 #
- CHORE: Constraint bump to
tracelet_platform_interface1.9.1. No iOS-side changes.
1.9.0 #
- FIX: Picks up the
tracelet_platform_interface1.9.0 fix that restoresextrasandverticespropagation foraddGeofence(#58). No native-side changes.
1.8.13 #
- PERF: Reduce first-fix latency on stationary → moving transitions.
LocationEngine.changePace(true)now fires an additional one-shotrequestLocation()so a fresh GPS fix arrives as soon as the hardware is warm, instead of waiting fordistanceFilteron the continuous stream (#54). - FIX: Bump iOS native SDK to 1.0.11.
1.8.12 #
- CHORE: Version bump for geofence/location
extrasround-trip fix intracelet_android(#51 follow-up). iOS already handled extras correctly; regression tests added to lock in parity.
1.8.11 #
- FIX: Guard against secondary FlutterEngine (e.g. Firebase background messaging) overwriting SDK singleton's event sender and callbacks (#51).
1.8.10 #
- FIX: Version bump for killed-state tracking fix in
tracelet_android(#50). - FIX: Bump iOS SDK to 1.0.10.
1.8.9 #
- FEAT: Add
syncIntervalsupport — timer-based HTTP sync viaDispatchSourceTimer(#50). - FEAT: Bump native SDK dependency to exact version
1.0.9.
1.8.8 #
- FIX: Fix
SubsystemTestsstatic property access forHttpSyncManagercallbacks. - FIX: Bump native SDK dependency to exact version
1.0.8.
1.8.7 #
- CHORE: Align federated package versions and include additional patch updates.
- FIX: Bump native SDK dependency to exact version
1.0.7.
1.8.6 #
- FIX:
getCurrentPosition(samples: 1)now usesstartUpdatingLocationinstead ofCLLocationManager.requestLocation()— forces a fresh GPS fix with proper timeout instead of returning stale cached locations (#46). - PERF: Remove per-batch
onRequestFreshHeadersinvocation — eliminates latency before every sync request. Token refresh handled byonAuthorizationRequiredon 401. - FIX: Bump native SDK dependency to exact version
1.0.6. - FIX: Privacy zones, audit trail, and encryption APIs now work before
ready()— guards relaxed fromisReadytomanager != nil.
1.8.5 #
- FIX:
getCurrentPosition()falls back to last known location whenCLLocationManagerreturns no fix (e.g. simulator, GPS-off) — fixesLOCATION_UNAVAILABLEerrors (#46). - FIX: Bump native SDK dependency to exact version
1.0.5.
1.8.4 #
- FIX: Pin native SDK dependency to exact version
1.0.4— prevents CocoaPods from auto-resolving to incompatible newer releases.
1.8.3 #
- FIX: Add
isReadyguards togetState(),setConfig(),reset(),getCurrentPosition(),changePace(),startSchedule(),stopSchedule()in Flutter bridge — returns safe defaults orNOT_READYerror instead of crashing (re-fixes #46).
1.8.2 #
- FIX:
TraceletSdk.stop()now checksisReadybefore accessing managers — prevents crash whenstop()is called beforeready(). - FIX:
TraceletHostApiImpl.stop()returnsNOT_READYPigeonError when called before initialization.
1.8.1 #
- FIX: Periodic mode no longer shows persistent location indicator — removed
CLBackgroundActivitySessionfrom periodic tracking (it caused the blue arrow to stay on permanently instead of briefly during each fix). - TEST: Add
BackgroundActivitySessionManager,ServiceSessionManager, andPeriodicModeBackgroundSessionunit tests.
1.8.0 #
- FIX: ConfigManager null-merge — filter NSNull values during merge so partial
setConfig()does not overwrite existing non-null config. - FIX: Add missing
import UIKitinLocationEngine.swiftforUIBackgroundTaskIdentifier. - FIX: Align location map format — snake_case accuracy keys → camelCase (
altitudeAccuracy,speedAccuracy,headingAccuracy), dead reckoningisCharging→is_charging. - FIX: DB
insertLocationreads camelCase accuracy keys with snake_case fallback;locationRowToMapoutputs camelCase. - FEAT: Add
destroySyncedLocations()— deletes only synced locations from the database. - FEAT: Auto-purge synced locations after successful HTTP sync in
HttpSyncManager. - TEST: Add 28 location map format tests, 4 unit tests for ConfigManager null-merge and
deleteSyncedLocations.
1.7.1 #
- FIX: ConfigManager null-merge — filter NSNull values during merge so partial
setConfig()does not overwrite existing non-null config. - FIX: Add missing
import UIKitinLocationEngine.swiftforUIBackgroundTaskIdentifier. - FEAT: Add
destroySyncedLocations()— deletes only synced locations from the database. - FEAT: Auto-purge synced locations after successful HTTP sync in
HttpSyncManager. - TEST: Add 4 unit tests for ConfigManager null-merge protection and
deleteSyncedLocations.
1.7.0 #
- FIX: Wire
headlessFallbackineventSenderFactory(preventive — ensures future factory consumers can route toHeadlessRunner). - FIX: Move podspec to repo root for CocoaPods trunk push compatibility.
- FEAT: Rewrite
EventDispatcherto use PigeonTraceletEventApiFlutterApi. - FEAT: Add
TraceletHostApiImplfor type-safe Pigeon HostApi dispatch. - REFACTOR: Extract native SDK to standalone
sdk/ios/module (CocoaPods:TraceletSDK, SPM package). - REFACTOR: Wire Flutter plugin to published TraceletSDK pod.
1.6.3-alpha.1 #
- FEAT: Rewrite
EventDispatcherto use PigeonTraceletEventApiFlutterApi instead of FlutterEventChannels. - FEAT: Add
TraceletHostApiImplfor type-safe Pigeon HostApi dispatch. - REFACTOR: Extract native SDK code to
sdk/ios/module. - CHORE: Update cross-package dependency constraints to
^1.6.3-alpha.1.
1.6.1 #
- FEAT: Add 401-aware retry — on HTTP 401 Unauthorized, invoke headless headers callback to refresh token, then retry once with updated dynamic headers.
1.6.0 #
- FEAT: Add SSL certificate pinning —
URLSessionDelegate-based validation with SHA-256 fingerprint matching via CommonCrypto. - FEAT: Add dynamic HTTP headers with runtime callback support and headless background execution.
- FEAT: Add route context — attach arbitrary metadata to synced locations.
- FEAT: Add custom sync body builder with headless callback support.
- CHORE: Update
tracelet_platform_interfacedependency constraint to^1.6.0.
1.5.0 #
- CHORE: Update
tracelet_platform_interfacedependency constraint to^1.5.0.
1.4.6 #
- FIX: Rename
PermissionManagertoTraceletPermissionManagerto avoid class name collision withpermission_handler_apple(#32). - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.6.
1.4.5 #
- FEAT: Auto-request temporary full accuracy (iOS 14+) when tracking starts with reduced accuracy authorization.
- TEST: Add XCTest unit tests for
buildLocationMap()locationSource classification andreducedAccuracyfield. - DOCS: Update INSTALL-IOS.md with
TraceletFullAccuracypurpose key documentation. - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.5.
1.4.4 #
- FEAT: iOS 14+ reduced accuracy detection — engine logs warnings when approximate location is active and tracks authorization transitions.
- FEAT: Add
reducedAccuracyflag to each location fix —truewhen iOS grants only approximate location (~5 km). - FEAT: Improved
locationSourceclassification — under reduced accuracy, source is classified ascellsince iOS returns coarse fixes. - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.4.
1.4.3 #
- FEAT: Add
locationSourceclassification to every location fix (gps,wifi,cell,unknown) based onhorizontalAccuracyheuristic. - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.3.
1.4.2 #
- FIX:
activateDeadReckoning()now retries via timer instead of silently returning whenlastLocationis nil. - FIX: Add debug logging to GPS-loss timer and dead reckoning activation flow.
- CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.2.
1.4.1 #
- FEAT: Dead reckoning — full IMU sensor fusion implementation (
DeadReckoningEngine). UsesCMDeviceMotion(fused accelerometer + gyroscope + magnetometer) for heading and step detection. Vehicle mode with acceleration integration. - FEAT: Auto-activation on GPS loss after configurable delay, auto-deactivation on GPS recovery or max duration.
- CHORE: Add dead reckoning config getters to
ConfigManager. - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.1.
1.4.0 #
- FEAT: Encrypted SQLite — database encryption via iOS Data Protection API (
NSFileProtectionComplete). - FEAT: Device attestation — App Attest (DCAppAttestService) integration with challenge generation, token caching, and periodic refresh (
DeviceAttestor). - FEAT: Remote config — fetch remote configuration via HTTPS with ETag caching and config-change event streaming.
- FEAT: Dead reckoning —
getDeadReckoningState()stub for future accelerometer/gyroscope-based position estimation. - FEAT: Carbon estimator —
getCarbonReport()returns CO₂ estimates from tracked locations using EU average emission factors. - CHORE: Add
DeviceCheckframework dependency. - CHORE: Update
tracelet_platform_interfacedependency constraint to^1.4.0.
1.3.6 #
- FIX:
getLocations()now honorsSQLQuery.startandSQLQuery.endtimestamp filtering. - FIX:
getCount()now accepts optionalSQLQueryfor time-bounded counting. - CHORE: Update cross-package dependency constraints to
^1.3.6.
1.3.5 #
- FIX: Fix
Unable to find module dependency: 'TraceletCore'Swift compiler error by consolidating SPM targets into a single module and removing invalid cross-module imports. - FIX: Add missing
AVFoundation,AudioToolbox, andNetworkframework linker settings inPackage.swift.
1.3.4 #
- CHORE: Update
tracelet_platform_interfacedependency constraint to^1.3.3.
1.3.3 #
- FIX: Bundle TraceletCore Swift source files directly inside the plugin package instead of depending on an unpublished local CocoaPod. Fixes unresolved
import TraceletCorewhen installed from pub.dev.
1.3.2 #
- PERF: Replace
Foundation UUID()with C-leveluuid_generate_random/uuid_unparse_lowerinLocationEngineandTraceletDatabase(I-M6).
1.3.1 #
- FIX:
getPersistenceExtras()now reads distinctpersistenceExtrasconfig key with backward-compatible fallback. - PERF:
markSynced()uses chunked SQL statements (500 UUIDs/chunk) instead of unbounded placeholder lists.
1.3.0 #
- FIX:
getState()always returnedenabled: falseon iOS —StateManager.toMap()flat-merged the config dictionary into the state dictionary, causing config keys (enabledfrom audit section,isMovingfrom motion section) to overwrite runtime state values. Config is now correctly nested under a"config"key, matching the Android implementation and the DartState.fromMap()contract (#26).
1.2.1 #
iOS↔Android Parity Fixes #
- FEAT: Add
ConfigManager.hasConfig()— returnstrueif a config has been persisted at least once (checks UserDefaults for stored config data). Matches existing AndroidConfigManager.hasConfig(). - FEAT: Add
StateManager.lastPeriodicLatitude/lastPeriodicLongitude— persisted coordinates for odometer computation across periodic tracking restarts. ReturnsNaNwhen no fix has been recorded; settingNaNremoves the persisted value. Matches AndroidStateManager.lastPeriodicLatitude/Longitude. - FEAT: Add
StateManager.addOdometer(distance:)— incremental odometer accumulation method. Matches AndroidStateManager.addOdometer(distance). - FEAT: Add
LocationEngine.stopAllWatchers()— clears all active watch-position subscriptions. Called automatically fromdestroy(). Matches AndroidLocationEngine.stopAllWatchers(). - FEAT: Add
TraceletEventSending.hasListener(eventName:)protocol method andEventDispatcher.hasListener(eventName:)implementation — checks if a Dart listener is attached for a given event channel. Accepts both full path (com.tracelet/events/location) and short name (location). Matches AndroidEventSender.hasListener(). - REFACTOR: All TraceletCore members made
publicfor cross-module access withuse_frameworks!CocoaPods integration.
1.2.0 #
- CHORE: Version bump for federation consistency with
tracelet_platform_interface1.2.0 (newNotificationPriorityandHashAlgorithmenums).
1.1.0 #
New Features #
- FEAT: Add native
DeltaEncoder(Swift) for delta-compressed HTTP sync payloads — mirrors the Dart implementation exactly for platform consistency. Encodes only field deltas between consecutive locations using shortened keys (la,lo,t,s,h,a,al,b), achieving 60–80% bandwidth reduction. Uses Foundation'sISO8601DateFormatterwith fractional seconds fallback for robust timestamp handling. - FEAT:
ConfigManagernow reads and applies the following new configuration fields from Dart:batteryBudgetPerHour(adaptive battery budget target),enableSparseUpdates,sparseDistanceThreshold,sparseMaxIdleSeconds(app-level deduplication),enableDeadReckoning,deadReckoningActivationDelay,deadReckoningMaxDuration(inertial navigation when GPS lost),enableDeltaCompression,deltaCoordinatePrecision(HTTP delta encoding), anddisableAutoSyncOnCellular(WiFi-only sync). - FEAT:
HttpSyncManagernow supportsdisableAutoSyncOnCellular— skips auto-sync when device is on cellular network, syncing only on WiFi. Also conditionally appliesDeltaEncoder.encode()to multi-location batches before HTTP upload whenenableDeltaCompressionis enabled, reducing upload size by 60–80%.
1.0.2 #
- FIX:
handleReset()unconditionally removed geofence registrations from CLLocationManager even whenstopOnTerminate: falsewas configured withtrackingMode=1(geofence mode). Geofences now survive the reset call so CLLocationManager continues monitoring regions after app termination (#23).
1.0.1 #
- FIX: HTTP auto-sync never triggered from automatic location tracking —
onLocationInserted()was only called from the manualinsertLocationhandler, not fromLocationEngine.persistLocationIfAllowed()(#21). - FIX:
ConfigManager.getHttpMethod()castIntasString, silently ignoringHttpMethod.put— now correctly maps0→ POST,1→ PUT. - FIX:
ConfigManager.getHttpHeaders()strict[String: String]cast could drop headers when platform channel delivers[String: Any]— now coerces values to strings. - FIX:
maxBatchSizedefault corrected from 100 to 250 to match Dart and Android defaults.
1.0.0 #
🎉 Stable Release #
- FEAT: First stable release of
tracelet_ios. - REFACTOR: Remove third-party company name references.
- All native iOS APIs are finalized and production-ready.
0.12.0 #
Performance Audit — 22 iOS issues resolved #
- PERF: Cache
ISO8601DateFormatteras static instance (I-C1, I-C2). - PERF: Call
UIDevice.isBatteryMonitoringEnabledonce at plugin initialization (I-C3). - PERF: Add serial
stateQueuefor thread-safe sync flag access (I-C4). - PERF: Use
BackgroundTaskHelper.shared.begin()with proper expiration handler (I-C5). - PERF: Reduce accelerometer to 10 Hz and deliver on background queue (I-H1).
- PERF: Set timer tolerance to 10% for iOS energy coalescing (I-H2).
- PERF: Use SQLite transactions for batch geofence inserts (I-H3).
- PERF: Throttle DB pruning to every 100 inserts (I-H4, I-H6).
- PERF: Move JSON serialization outside DB queue lock (I-H5).
- PERF: Default
pausesLocationUpdatesAutomaticallytotrue(I-M1). - PERF: Make
activityTypeconfigurable viagetActivityType()mapping (I-M2). - PERF: Reuse
URLSession—getAllTaskscancel instead ofinvalidateAndCancel(I-M3). - PERF: Defer
BGAppRefreshTask.setTaskCompleteduntil async location fix returns (I-M4). - PERF: Find monitored region by identifier instead of creating dummy
CLCircularRegion(I-M5). - PERF: Add in-memory privacy zone cache with CRUD invalidation (I-M7).
- PERF: Add in-memory geofence cache with CRUD invalidation (I-M8).
- PERF: Lazy-init
CMMotionActivityManagerandCMPedometerfor accelerometer-only mode (I-L1). - PERF: Remove duplicate
haversine()fromGeofenceManager, call module-level function (I-L3). - PERF: Remove dead
@available(iOS 14)self-assign no-op (I-L4). - REFACTOR: Remove trivial
isMoreRestrictive()wrapper, inlineisActionMoreRestrictive()call (I-L5). - CHORE: Add CoreLocation import to
ConfigManager.swiftforCLActivityType.
0.11.5 #
- FIX: Persist polygon geofence
verticesto SQLite — addvertices TEXTcolumn withPRAGMA table_infomigration for existing installs, and JSON serialization/deserialization ininsertGeofence()/geofenceRowToMap(). - FIX: Use
NSNumberbridging forJSONSerializationvertex deserialization (fixes silent cast failure with[[Double]]). - FIX: Handle heterogeneous vertex arrays — skip non-array entries instead of failing the entire cast.
- TEST: Add XCTest tests for geofence vertices CRUD (11 tests covering round-trip, validation, edge cases).
- TEST: Add DB migration integration tests — column addition, data preservation, idempotency, multi-geofence migration, fresh install.
0.11.4 #
- FIX: Revert over-aggressive
allowsBackgroundLocationUpdatesand significant-location guards — When In Use permission now works correctly for foreground and background tracking. iOS enforces permission at the OS level; only the killed-state entry point (autoResumeTracking) requires Always authorization.
0.11.3 #
- FIX: Add
.authorizedAlwaysguard toautoResumeTracking()— prevents "When In Use" permission from triggering tracking after app is relaunched from killed state via significant-location-change. - FIX: Guard
allowsBackgroundLocationUpdatesinconfigureLocationManager()andperformPeriodicFix()— only set totruewhen Always authorization is granted.
0.11.2 #
- CHORE: Tighten
tracelet_platform_interfaceconstraint to^0.11.2.
0.11.1 #
- FIX: Set
event: "periodic"in alldidUpdateLocationscode paths for periodic tracking (was empty string). - FEAT: Add
canScheduleExactAlarms(returnstrue) andopenExactAlarmSettings(returnsfalse) method channel stubs. - CHORE: Add NSLog diagnostic logging to
startPeriodic()andperformPeriodicFix(). - CHORE: Bump platform interface to 0.11.1.
0.11.0 #
- FEAT:
AuditTrailManager— SHA-256 hash chain with SQLite persistence and UserDefaults chain state. - FEAT:
PrivacyZoneManager— Haversine distance-based zone evaluation with exclude, degrade, and event-only actions. - FEAT: Privacy zones database table with CRUD operations.
- FEAT: Audit trail database table with hash chain linkage.
- FEAT:
ConfigManagergetters for audit and privacy zone configuration. - CHORE: Bump
tracelet_platform_interfaceto ^0.11.0.
0.10.0 #
- FEAT: Periodic mode — GPS-friendly interval tracking via
startPeriodic(). Timer-based scheduling with background location toggling per fix. - FEAT:
ConfigManagerperiodic config getters for interval, accuracy, foreground service, and exact alarms. - FIX:
ConfigManager.swiftescaped string literals causing Swift compilation failure. - CHORE: Bump
tracelet_platform_interfaceto ^0.10.0.
0.9.1 #
- FIX: Safe optional unwrap of
UIBackgroundTaskIdentifierinHttpSyncManager.syncNextBatch()— fixes Swift compiler error.
0.9.0 #
- FEAT: HTTP sync retry engine — configurable retry with exponential backoff for transient 5xx, 429, and timeout failures. Defers sync on connectivity loss via
NWPathMonitor. Batch continuation loop. - FEAT: Configurable motion sensitivity —
MotionDetectorreadsshakeThreshold,stillThreshold,stillSampleCountfromConfigManagerat runtime (auto-converts m/s² to g-force). - CHORE: Bump
tracelet_platform_interfaceto ^0.9.0.
0.8.3 #
- FEAT: Proximity-based geofence auto-load/unload — only geofences within
geofenceProximityRadiusare registered with CLLocationManager, sorted by distance, capped at 20 (iOS limit). Enables monitoring thousands of geofences. - FEAT:
GeofenceManager.updateProximity()— re-evaluates which geofences to monitor on every location update, dynamically swapping region registrations as the device moves. - FEAT:
geofencesChangeevent fires withon/offarrays when geofences are activated/deactivated from proximity monitoring. - FEAT:
maxMonitoredGeofencesconfig respected — caps simultaneously monitored regions below the platform limit. - CHORE: Bump
tracelet_platform_interfaceto ^0.8.3.
0.8.2 #
- DOCS: Improve README visuals with combined Android & iOS demo image.
0.8.1 #
- FEAT:
BackgroundTaskHelper— central thread-safe utility wrappingUIApplication.beginBackgroundTaskfor safe background execution of native operations. - FEAT: iOS 17+
CLBackgroundActivitySessionsupport viaBackgroundActivitySessionManager— extends background runtime for location-tracking apps. - FEAT: iOS 18+
CLServiceSessionsupport viaServiceSessionManager— maintains authorization state during background execution. - PERF: Wrap
LocationEngine.didUpdateLocationsin background task — protects persist + dispatch chain from iOS suspension. - PERF: Wrap
HttpSyncManager.sync()in background task — protects entire HTTP upload + DB cleanup cycle. - PERF: Wrap
HeadlessRunner.dispatchEvent()engine boot in background task — ensures Dart engine starts fully before iOS reclaims resources. - PERF: Wrap all
TraceletIosPluginlifecycle transitions (handleStop,handleReset,onStopRequested,handleScheduleStop,stopAfterElapsedTimer) in background tasks. - FIX:
preventSuspendManager.start()now called instartGeofences()— was missing, causing audio keep-alive to not activate in geofence-only mode. - FIX:
preventSuspendManager.stop()now called in all stop paths (reset, stopOnStationary, scheduleStop, stopAfterElapsed) — was only called inhandleStop(). - FIX:
setConfig()now togglespreventSuspendManagermid-session whenpreventSuspendchanges. - FIX:
reset()now callscancelStopAfterElapsedTimer()— was leaving stale timer running after reset. - FIX: iOS 17+/18+ session managers wired into all lifecycle paths (start, stop, startGeofences, reset, scheduleStart/Stop, stopOnStationary, stopAfterElapsed).
0.8.0 #
- FEAT: OEM compatibility stubs —
getSettingsHealthreturnsisAggressiveOem: false(iOS has no OEM power management issues),openOemSettingsreturnsfalse. - DOCS: Update README with OEM compatibility note and documentation link.
- CHORE: Bump
tracelet_platform_interfaceto ^0.8.0.
0.7.1 #
- DOCS: Add mock location detection feature to README with platform-specific detection details.
- CHORE: Bump
tracelet_platform_interfaceto ^0.7.1.
0.7.0 #
- FEAT: Mock location detection —
isLocationMock()usesCLLocationSourceInformation(iOS 15+) to detect simulated locations. - FEAT: Heuristic mock detection (level 2) — timestamp drift check (> 10s between location timestamp and system time = suspicious).
- FEAT:
buildLocationMap()includesmockflag andmockHeuristicsmetadata map (timestampDriftMs, platformFlagMock). - FEAT: Native-level mock rejection — when
rejectMockLocationsis enabled, drops mocked locations before sending to Dart and firesProviderChangeEvent.mockLocationsDetected. - FEAT:
ConfigManager.getMockDetectionLevel()andgetRejectMockLocations()getters. - CHORE: Bump
tracelet_platform_interfaceto ^0.7.0.
0.6.1 #
- REFACTOR: Remove 6 dead
ConfigManagermethods for filtering migrated to Dart in 0.6.0 (getDisableElasticity,getElasticityMultiplier,getFilterPolicy,getMaxImpliedSpeed,getTrackingAccuracyThreshold,getUseKalmanFilter). - REFACTOR: Remove dead
EventDispatcher.sendTrip()and"trip"channel registration — trip events now from DartTripManager. - CHORE: Bump
tracelet_platform_interfaceto ^0.6.1.
0.6.0 #
- REFACTOR: Remove duplicate location filtering from
LocationEngine.didUpdateLocations()— elasticity, distance filter, accuracy filter, and speed filter now handled by shared DartLocationProcessor. - REFACTOR: Replace
GeofenceManager.evaluateHighAccuracyProximity()with no-op stub — proximity evaluation moved to shared DartGeofenceEvaluator. - CHORE: Bump
tracelet_platform_interfaceto ^0.6.0.
0.5.5 #
- FIX:
onScheduleevent now sends full state map (viastateManager.toMap()) instead of partial["state": "on", "enabled": true]— fixesState.fromMap()crash on schedule events.
0.5.4 #
- FIX: Heartbeat event now wraps location data in
{"location": ...}to matchHeartbeatEvent.fromMap()— fixes heartbeat always returning zero coordinates. - FIX: Heartbeat falls back to last known location (via
buildLocationMap()) whengetCurrentPositionreturns null.
0.5.3 #
- CHORE: Bump
tracelet_platform_interfaceto ^0.5.3.
0.5.2 #
- FEAT: Accelerometer-only motion detection mode — when
disableMotionActivityUpdatesistrue, usesCMMotionManagerraw accelerometer for permission-free stationary↔moving detection (noNSMotionUsageDescriptionrequired). - FEAT:
getMotionAuthorizationStatus()/requestMotionPermission()return3(granted) immediately in accelerometer-only mode — no OS dialog shown. - PERF: Reuse shared
CMMotionManagerinstance for sensor queries instead of creating throwaway instances. - FIX: Auto-fallback to accelerometer-only when
CMMotionActivityManager.isActivityAvailable()returnsfalse.
0.5.1 #
- DOCS: Rewrite README with proper description, setup guide link, and related packages table.
0.5.0 #
- CHORE: Bump
tracelet_platform_interfaceto ^0.5.0. - CHORE: Bump version to 0.5.0.
0.4.0 #
- FEAT:
getMotionPermissionStatus()/requestMotionPermission()— CMMotionActivityManager authorization check. - FIX: Speed always zero in motionchange events — track
lastEffectiveSpeedin LocationEngine. - FIX: "Upgrade to Always" dialog not appearing — fix
handleStartisMoving initialization. - FIX: MotionDetector motion state bugs — proper accelerometer + activity recognition lifecycle.
- CHORE: Bump
tracelet_platform_interfaceto ^0.4.0.
0.3.0 #
- FEAT: One-shot location via
getCurrentPosition()withpersist,samples,maximumAge, andextrasparameters. - FEAT: Multi-sample collection with
distanceFilter = kCLDistanceFilterNoneandDispatchQueuetimeout guard. - FEAT:
getLastKnownLocation()— prefers own cached location, falls back toCLLocationManager.location. - FEAT:
ForegroundServiceConfig.enabledsupport. - FIX: Add
CLAuthorizationStatusguard ingetCurrentPosition()— returns nil if not authorized instead of hanging. - FIX: Single-sample path now sets
desiredAccuracy = kCLLocationAccuracyBestbeforerequestLocation(). - BREAKING: Requires
tracelet_platform_interface: ^0.3.0.
0.2.4 #
- Fix LICENSE file format for proper SPDX detection on pub.dev.
0.2.3 #
- Fix
ConfigManager.setConfig()— flatten nested section sub-maps (geo,app,http, etc.) sent by Dart before processing. Fixes all user config values being silently ignored in favor of defaults.
0.2.2 #
- Fix duplicate keys in
ConfigManager.defaultConfig()dictionary literal causing runtime crash.
0.2.1 #
- Version bump for coordinated release.
0.2.0 #
- Add Swift Package Manager support.
- Fix podspec homepage URL.
- Fix podspec source_files and resource_bundles paths for SPM layout.
- Add SPDX
license: Apache-2.0identifier for pub.dev scoring.
0.1.0 #
- Initial release.
- CLLocationManager-based location tracking.
- CoreMotion activity recognition.
- SQLite3 persistence.
- HTTP auto-sync with URLSession.
- CLCircularRegion geofencing.
- Headless FlutterEngine execution.
- BGTaskScheduler integration.
- Significant-change monitoring support.