Skip to content

chore(geofence): acquire location without emitting analytics events#1140

Merged
mrehan27 merged 2 commits into
feature/geofence-on-devicefrom
mbl-1978-geofence-internal-location-api
Jul 3, 2026
Merged

chore(geofence): acquire location without emitting analytics events#1140
mrehan27 merged 2 commits into
feature/geofence-on-devicefrom
mbl-1978-geofence-internal-location-api

Conversation

@mrehan27

@mrehan27 mrehan27 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What & why

Lets hosts use on-device geofencing without emitting CIO Location Update
analytics events or enriching identify context with precise location. Geofencing
needs a fix even when location tracking is .off; today acquisition and tracking
are coupled, so a geofence-only customer would leak precise location.

Changes

Location module

  • New internal @_spi(Geofence) requestLocationUpdateSilently(): acquires a
    one-shot fix, posts LocationAcquiredEvent, records it as last-known only — no
    CIO Location Update track, not persisted, not in identify enrichment. Runs
    regardless of LocationConfig.mode; still requires location permission.
  • Split last-location storage: in-memory lastKnownLocation (any source, incl.
    silent) backs getLastKnownLocation(); the persisted cache (analytics/identify
    • 24h/1km guardrails) stays tracking-only.

Geofence module

  • GeofenceLocationMode { automatic (default), manual } on GeofenceModuleConfig.
    .automatic self-acquires when geofencing needs a fix and none is available;
    .manual waits for the host and never acquires location on its own.
  • Public CustomerIO.geofence.refreshFromCurrentLocation() — the way to drive
    geofencing in .manual, and a forced refresh in .automatic. Arms an explicit
    refresh, then requests a silent fix.
  • Run the refresh decision once at app launch (SDK/module init), alongside the
    existing identify and location-acquired triggers.

Sample app (APN-UIKit): on permission grant, calls
CustomerIO.geofence.refreshFromCurrentLocation() instead of
requestLocationUpdate().

Behavior parity

Mirrors the Android implementation: silent primitive, cache split, mode enum,
facade, explicit-refresh arm, and the refresh decision on app launch + identify +
location-acquired.

Tests

  • Storage split: last-known reflects any source, falls back to persisted cache,
    cleared on reset; persisted cache untouched by silent fixes.
  • Location services: silent acquisition runs (and caches last-known) even when
    tracking is .off, but emits no analytics.
  • Coordinator: silent update records last-known + posts event but does not persist
    or track.
  • Geofence: config default/manual; refresh from cached/registration anchor at
    launch; auto-acquire at launch in .automatic; .manual arms the refresh but
    never self-acquires; identify triggers a refresh; explicit-refresh arm; no
    false-arm when an anchor already exists.

Note

Medium Risk
Changes how location fixes flow into analytics, identify enrichment, and geofence refresh timing (including launch and user-reset), which affects privacy behavior and geofence correctness across sessions.

Overview
Decouples geofence-only location use from analytics and identify enrichment so apps can sync nearby geofences without emitting CIO Location Update or persisting precise coordinates for profile context.

The Location module adds an internal @_spi(Geofence) requestLocationUpdateSilently() path that still posts LocationAcquiredEvent and updates in-memory last-known, but skips persisted cache, tracks, and identify enrichment when track is false. processLocationUpdate(_:track:) gates persistence and pipeline sync on track; public getLastKnownLocation() now reads the split storage (in-memory last-known with fallback to the tracking cache). Silent acquisition runs even when LocationConfig.mode is .off.

The Geofence module adds GeofenceLocationMode (.automatic / .manual), public CustomerIO.geofence.refreshFromCurrentLocation(), launch-time refresh alongside identify/location-acquired triggers, identified-user gating, explicit-refresh arming cleared on reset, and .automatic self-acquire via silent location when no anchor exists. The sample app calls refreshFromCurrentLocation() on permission grant instead of requestLocationUpdate().

Reviewed by Cursor Bugbot for commit 9c5a3c6. Bugbot is set up for automated code reviews on this repo. Configure here.

@mrehan27 mrehan27 requested a review from a team as a code owner July 2, 2026 12:10
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Sample app builds 📱

Below you will find the list of the latest versions of the sample apps.
It's recommended to always download the latest builds to test this PR accurately.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

SDK binary size reports 📊

SDK binary size of this PR
    FILE SIZE        VM SIZE    
 --------------  -------------- 
   3.1%  33.8Ki   3.1%  33.8Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/Event.swift
   2.5%  26.9Ki   2.5%  27.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/MessagingPush.swift
   2.2%  24.4Ki   2.2%  24.4Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/AnonymousMessageManager.swift
   2.2%  23.4Ki   2.2%  23.4Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/DataPipeline.swift
   2.1%  23.3Ki   2.1%  23.3Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageMiddleware.swift
   2.0%  22.0Ki   2.0%  22.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/SseConnectionManager.swift
   1.7%  19.0Ki   1.7%  19.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/GeofenceStorage.swift
   1.6%  17.7Ki   1.6%  17.7Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageAction.swift
   1.6%  17.5Ki   1.6%  17.5Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/MessageManager.swift
   1.6%  17.5Ki   1.6%  17.5Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/EngineWeb/AnyEncodable.swift
   1.6%  17.1Ki   1.6%  17.1Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/SseEventParser.swift
   1.5%  16.0Ki   1.5%  16.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/BackgroundDeliveryContextStore.swift
   1.4%  15.6Ki   1.4%  15.6Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/DefaultNotificationInbox.swift
   1.4%  14.9Ki   1.4%  14.9Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/QueueStorage.swift
   1.3%  14.6Ki   1.3%  14.7Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceSyncCoordinator.swift
   1.3%  14.2Ki   1.3%  14.2Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Gist.swift
   1.3%  14.0Ki   1.3%  14.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Monitor/CoreLocationGeofenceMonitor.swift
   1.3%  13.9Ki   1.3%  13.9Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/autogenerated/AutoDependencyInjection.generated.swift
   1.2%  13.4Ki   1.2%  13.4Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Push/PendingPushDeliveryStore.swift
   1.2%  13.2Ki   1.2%  13.2Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/CombinedCacheEventBusHandler.swift
   1.2%  12.8Ki   1.2%  12.8Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageState.swift
   1.2%  12.6Ki   1.2%  12.6Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/autogenerated/AutoDependencyInjection.generated.swift
   1.1%  12.3Ki   1.1%  12.3Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/DataPipelineImplementation.swift
   1.1%  12.1Ki   1.1%  12.1Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/EventStorage.swift
   1.1%  11.9Ki   1.1%  11.9Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/SseService.swift
   1.1%  11.7Ki   1.1%  11.7Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/EventMemoryStorage.swift
   1.0%  11.3Ki   1.0%  11.3Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/CustomerIOInstance.swift
   1.0%  11.2Ki   1.0%  11.2Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/QueueManager.swift
   1.0%  11.2Ki   1.0%  11.2Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Event/GeofenceEventTracker.swift
   1.0%  11.1Ki   1.0%  11.1Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/SseLifecycleManager.swift
   1.0%  10.9Ki   1.0%  10.9Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Request/TrackDeliveryEventRequestBody.swift
   0.9%  10.0Ki   0.9%  10.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageReducer.swift
   0.9% 10.00Ki   0.9% 10.00Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Api/GeofenceApiResponse.swift
   0.9%  9.70Ki   0.9%  9.70Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageManager.swift
   0.9%  9.58Ki   0.9%  9.58Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/MessagingPushImplementation.swift
   0.9%  9.51Ki   0.9%  9.51Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/PendingGeofenceMetricStore.swift
   0.9%  9.47Ki   0.9%  9.47Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/JsonAdapter.swift
   0.9%  9.44Ki   0.9%  9.44Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/NSEPushCoordinator.swift
   0.9%  9.38Ki   0.9%  9.38Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/EngineWeb/EngineWeb.swift
   0.8%  8.99Ki   0.8%  8.99Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/GeofenceState.swift
   0.8%  8.80Ki   0.8%  8.80Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Type/PushNotification.swift
   0.8%  8.77Ki   0.8%  8.77Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/DataPipelineImplementation+BGQ.swift
   0.8%  8.50Ki   0.8%  8.50Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceDistanceFilter.swift
   0.8%  8.39Ki   0.8%  8.39Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/InAppMessageStore.swift
   0.8%  8.30Ki   0.8%  8.30Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/FileLastLocationStateStore.swift
   0.8%  8.30Ki   0.8%  8.30Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/URLComponents.swift
   0.8%  8.16Ki   0.8%  8.16Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/CoreLocationProvider.swift
   0.7%  7.95Ki   0.7%  7.95Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Views/GistInlineInAppMessageView.swift
   0.7%  7.86Ki   0.7%  7.86Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/DIGraphShared.swift
   0.7%  7.83Ki   0.7%  7.83Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/SseRetryHelper.swift
   0.7%  7.52Ki   0.7%  7.53Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceModuleState.swift
   0.7%  7.32Ki   0.7%  7.32Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/PendingGeofenceMetric.swift
   0.7%  7.13Ki   0.7%  7.13Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/BackgroundDeliveryHttpClient.swift
   0.7%  7.07Ki   0.7%  7.07Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/RichPush/RichPushHttpClient.swift
   0.7%  7.07Ki   0.7%  7.07Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/KeyValueStorage.swift
   0.6%  6.87Ki   0.6%  6.87Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Migration/DataPipelineMigrationAssistant.swift
   0.6%  6.76Ki   0.6%  6.76Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/LocationServices.swift
   0.6%  6.75Ki   0.6%  6.75Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/AutoTrackingScreenViews.swift
   0.6%  6.54Ki   0.6%  6.54Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/LastLocationState.swift
   0.6%  6.48Ki   0.6%  6.48Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceBootstrap.swift
   0.6%  6.42Ki   0.6%  6.42Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/ModalViewManager.swift
   0.6%  6.25Ki   0.6%  6.25Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Views/UIKitInline.swift
   0.6%  6.10Ki   0.6%  6.10Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/Type/InboxMessage.swift
   0.6%  5.99Ki   0.6%  5.99Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Integration/CioProviderAgnosticAppDelegate.swift
   0.5%  5.41Ki   0.5%  5.41Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Push/PendingPushDeliveryMetric.swift
   0.5%  5.37Ki   0.5%  5.37Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Type/QueueTaskMetadata.swift
   0.5%  5.11Ki   0.5%  5.11Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Views/SwiftUIInline.swift
   0.5%  5.08Ki   0.5%  5.08Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Type/QueueTask.swift
   0.5%  5.07Ki   0.5%  5.07Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/UserNotificationsFramework/Wrappers.swift
   0.5%  4.94Ki   0.5%  4.94Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Response/ErrorMessageResponse.swift
   0.4%  4.88Ki   0.4%  4.88Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/Geofence.swift
   0.4%  4.86Ki   0.4%  4.86Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Config/SDKConfigBuilder.swift
   0.4%  4.84Ki   0.4%  4.84Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceSyncCoordinator+RefreshDecision.swift
   0.4%  4.84Ki   0.4%  4.84Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/LastLocationStorage.swift
   0.4%  4.78Ki   0.4%  4.78Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Migration/TrackEventMigrationType.swift
   0.4%  4.77Ki   0.4%  4.77Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/MessagingInApp.swift
   0.4%  4.62Ki   0.4%  4.62Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/HeartbeatTimer.swift
   0.4%  4.53Ki   0.4%  4.53Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/Models/Message.swift
   0.4%  4.35Ki   0.4%  4.35Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Queue.swift
   0.4%  4.17Ki   0.4%  4.17Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Config/MessagingPushConfigBuilder.swift
   0.4%  4.14Ki   0.4%  4.14Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/MessagingInAppImplementation.swift
   0.4%  4.05Ki   0.4%  4.05Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Views/InlineMessageBridgeView.swift
   0.4%  3.93Ki   0.4%  3.93Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/RichPush/RichPushRequestHandler.swift
   0.4%  3.81Ki   0.4%  3.81Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Api/GeofenceApiService.swift
   0.4%  3.81Ki   0.4%  3.81Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Request/MetricRequest.swift
   0.3%  3.60Ki   0.3%  3.60Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/GistDelegate.swift
   0.3%  3.59Ki   0.3%  3.59Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/LocationModuleState.swift
   0.3%  3.48Ki   0.3%  3.48Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/HttpRequestRunner.swift
   0.3%  3.45Ki   0.3%  3.45Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/Network/InboxMessageResponse.swift
   0.3%  3.41Ki   0.3%  3.41Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/Log.swift
   0.3%  3.39Ki   0.3%  3.39Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/Atomic.swift
   0.3%  3.38Ki   0.3%  3.38Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Collections.swift
   0.3%  3.36Ki   0.3%  3.36Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/AsyncOperation.swift
   0.3%  3.35Ki   0.3%  3.35Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Integration/CioNotificationCenterDelegate.swift
   0.3%  3.33Ki   0.3%  3.33Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceModule.swift
   0.3%  3.32Ki   0.3%  3.32Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Views/GistModalViewController.swift
   0.3%  3.27Ki   0.3%  3.27Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Logger+Geofence.swift
   0.3%  3.26Ki   0.3%  3.26Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/NSEPushCoordinatorState.swift
   0.3%  3.25Ki   0.3%  3.25Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/MessageTracking.swift
   0.3%  3.23Ki   0.3%  3.23Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/StringExtensions.swift
   0.3%  3.20Ki   0.3%  3.20Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/BaseNetwork.swift
   0.3%  3.16Ki   0.3%  3.16Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Module/ModuleTopLevelObject.swift
   0.3%  3.14Ki   0.3%  3.14Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/ModalMessageManager.swift
   0.3%  3.14Ki   0.3%  3.14Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/RichPushDeliveryTracking.swift
   0.3%  3.12Ki   0.3%  3.12Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/InlineMessageManager.swift
   0.3%  3.11Ki   0.3%  3.11Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/DeviceContexualAttributes.swift
   0.3%  2.99Ki   0.3%  2.99Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/GistQueueNetwork.swift
   0.3%  2.96Ki   0.3%  2.96Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/ManualPushHandling+UserNotifications.swift
   0.3%  2.94Ki   0.3%  2.94Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/CioEventBus.swift
   0.3%  2.93Ki   0.3%  2.93Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/FileStorage.swift
   0.3%  2.91Ki   0.3%  2.91Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/EngineWeb/EngineWebConfiguration.swift
   0.3%  2.82Ki   0.3%  2.82Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/StringAnyEncodable.swift
   0.3%  2.74Ki   0.3%  2.74Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/DeviceInfo.swift
   0.2%  2.57Ki   0.2%  2.57Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/HttpRequestError.swift
   0.2%  2.52Ki   0.2%  2.52Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/DateExtensions.swift
   0.2%  2.50Ki   0.2%  2.50Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Type/LocationProviderTypes.swift
   0.2%  2.50Ki   0.2%  2.50Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/HttpRequestParams.swift
   0.2%  2.49Ki   0.2%  2.49Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/Type/InboxMessageFactory.swift
   0.2%  2.45Ki   0.2%  2.45Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Task Data/DeletePushNotificationQueueTaskData.swift
   0.2%  2.40Ki   0.2%  2.40Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Dictionaries.swift
   0.2%  2.35Ki   0.2%  2.35Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/IdentifyContextPlugin.swift
   0.2%  2.34Ki   0.2%  2.34Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/GeofenceConfig.swift
   0.2%  2.30Ki   0.2%  2.30Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/EngineWeb/EngineEventHandler.swift
   0.2%  2.27Ki   0.2%  2.27Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/Context.swift
   0.2%  2.25Ki   0.2%  2.25Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/autogenerated/AutoDependencyInjection.generated.swift
   0.2%  2.23Ki   0.2%  2.23Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Util/DeviceAttributesProvider.swift
   0.2%  2.22Ki   0.2%  2.22Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/Core/Subscription.swift
   0.2%  2.20Ki   0.2%  2.20Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/SystemLogger.swift
   0.2%  2.11Ki   0.2%  2.11Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/DataPipelinePublishedEvents.swift
   0.2%  2.08Ki   0.2%  2.08Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Task Data/IdentifyProfileQueueTaskData.swift
   0.2%  2.06Ki   0.2%  2.06Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/SdkCommonLoggerLogger.swift
   0.2%  2.02Ki   0.2%  2.02Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Task Data/RegisterPushNotificationQueueTaskData.swift
   0.2%  2.00Ki   0.2%  2.00Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPushAPN/Integration/CioAppDelegateAPN.swift
   0.2%  1.95Ki   0.2%  1.95Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/DIGraphShared+PendingPushDeliveryStore.swift
   0.2%  1.92Ki   0.2%  1.92Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized.swift
   0.2%  1.89Ki   0.2%  1.89Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceMonitorBinder.swift
   0.2%  1.86Ki   0.2%  1.86Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/LockManager.swift
   0.2%  1.86Ki   0.2%  1.86Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Type/QueueTaskRunResults.swift
   0.2%  1.82Ki   0.2%  1.82Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/CustomerIO+Events.swift
   0.2%  1.74Ki   0.2%  1.74Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Models/InAppMessageResponse.swift
   0.2%  1.66Ki   0.2%  1.66Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/KeyValueStorageKey.swift
   0.2%  1.65Ki   0.2%  1.65Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Util/DictionarySanitizer.swift
   0.1%  1.63Ki   0.1%  1.63Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/NSEDeliveryContinuationBox.swift
   0.1%  1.58Ki   0.1%  1.58Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Type/QueueTaskType.swift
   0.1%  1.55Ki   0.1%  1.55Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/LocationLifecycleObserver.swift
   0.1%  1.52Ki   0.1%  1.52Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/LocationSyncCoordinator.swift
   0.1%  1.46Ki   0.1%  1.46Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Type/LocationData.swift
   0.1%  1.44Ki   0.1%  1.44Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Config/MessagingInAppConfigBuilder.swift
   0.1%  1.43Ki   0.1%  1.43Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/DictionaryExtension.swift
   0.1%  1.41Ki   0.1%  1.41Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Task Data/TrackEventQueueTaskData.swift
   0.1%  1.41Ki   0.1%  1.41Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Views/GistView.swift
   0.1%  1.38Ki   0.1%  1.38Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Request/PushMetric.swift
   0.1%  1.37Ki   0.1%  1.37Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/CustomerIO.swift
   0.1%  1.31Ki   0.1%  1.31Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Extensions/GistExtensions.swift
   0.1%  1.28Ki   0.1%  1.28Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/UIKitWrapper.swift
   0.1%  1.25Ki   0.1%  1.25Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/UIColor+Hex.swift
   0.1%  1.24Ki   0.1%  1.24Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/ThreadUtil.swift
   0.1%  1.23Ki   0.1%  1.23Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/QueueInventoryMemoryStore.swift
   0.1%  1.20Ki   0.1%  1.20Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/LogManager.swift
   0.1%  1.15Ki   0.1%  1.15Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/RichPush/RichPushRequest.swift
   0.1%  1.14Ki   0.1%  1.14Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Models/QueueMessagesResponse.swift
   0.1%  1.12Ki   0.1%  1.12Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Request/InAppMetric.swift
   0.1%  1.11Ki   0.1%  1.11Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/RealAppLifecycleNotifying.swift
   0.1%  1.09Ki   0.1%  1.09Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/CustomerIO+Segment.swift
   0.1%  1.06Ki   0.1%  1.08Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/DeviceExtension.swift
   0.1%  1.07Ki   0.1%  1.08Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPushAPN/MessagingPushAPN.swift
   0.1%  1.07Ki   0.1%  1.07Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Type/GeofenceTransition.swift
   0.1%  1.06Ki   0.1%  1.06Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Util/ProfileEnrichmentAttributesMerger.swift
   0.1%  1.04Ki   0.1%  1.04Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/LocationFilter.swift
   0.1%  1.02Ki   0.1%  1.02Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Config/DataPipelineConfigOptions.swift
   0.1%  1.01Ki   0.1%  1.01Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Endpoints/LogEndpoint.swift
   0.1%  1.01Ki   0.1%  1.01Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Type/ScreenView.swift
   0.1%  1.00Ki   0.1%  1.00Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/MockCollection.swift
   0.1%    1008   0.1%    1008    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/GlobalDataStore.swift
   0.1%     996   0.1%     996    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Coordinator/LocationProfileEnrichmentProvider.swift
   0.1%     984   0.1%     984    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/LastSyncRecord.swift
   0.1%     980   0.1%     980    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/SdkClient.swift
   0.1%     980   0.1%     980    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Util/DataPipelinesLogger.swift
   0.1%     956   0.1%     956    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Push/AppGroupIdentifier.swift
   0.1%     924   0.1%     924    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/CIOApiEndpoint.swift
   0.1%     876   0.1%     876    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/UserAgentUtil.swift
   0.1%     836   0.1%     836    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Managers/InboxMessageCacheManager.swift
   0.1%     828   0.1%     828    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Logger+Location.swift
   0.1%     792   0.1%     792    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/AnyEncodable.swift
   0.1%     784   0.1%     784    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/SdkConfig.swift
   0.1%     768   0.1%     768    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Util/PushNotificationLogger.swift
   0.1%     740   0.1%     740    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPushAPN/MessagingPushAPN+PushConfigs.swift
   0.1%     732   0.1%     732    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Type/CustomerIOParsedPushPayload.swift
   0.1%     724   0.1%     724    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/RingBuffer.swift
   0.1%     672   0.1%     672    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/ProfileEnrichment/ProfileEnrichmentRegistryImpl.swift
   0.1%     656   0.1%     656    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/RichPush/RichPushDeliveryTracker.swift
   0.1%     632   0.1%     632    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/DataPipelineImplementation+GeofenceObserver.swift
   0.1%     612   0.1%     612    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/DeepLinkUtil.swift
   0.1%     596   0.1%     596    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/ScreenFilterPlugin.swift
   0.1%     596   0.1%     596    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/Config/MessagingPushConfigOptions.swift
   0.1%     596   0.1%     596    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/UserNotificationsFramework/UserNotificationsFrameworkAdapter.swift
   0.1%     592   0.1%     592    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPushAPN/MessagingPush+APN.swift
   0.1%     580   0.1%     580    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/Environment.swift
   0.1%     566   0.1%     566    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Utilities/HTTPMethod.swift
   0.1%     564   0.1%     564    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Extensions/UIViewExtensions.swift
   0.0%     548   0.0%     548    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/Request/EmptyRequestBody.swift
   0.0%     524   0.0%     524    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/RichPush/RichPushRequestHandling.swift
   0.0%     520   0.0%     520    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Type/Region.swift
   0.0%     516   0.0%     516    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/Logger.swift
   0.0%     508   0.0%     508    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/UIKitExtensions.swift
   0.0%     492   0.0%     492    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Background Queue/Type/QueueStatus.swift
   0.0%     492   0.0%     492    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Type/GeofenceMetric.swift
   0.0%     472   0.0%     472    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/BackgroundDeliveryHttpHelpers.swift
   0.0%     468   0.0%     468    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/Encodable.swift
   0.0%     444   0.0%     444    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Hashable.swift
   0.0%     440   0.0%     440    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/ProfileStore.swift
   0.0%     428   0.0%     428    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/LocationModule.swift
   0.0%     416   0.0%     416    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Utilities/ElapsedTimer.swift
   0.0%     404   0.0%     404    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/autogenerated/AutoDependencyInjection.generated.swift
   0.0%     400   0.0%     400    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/Core/Store.swift
   0.0%     392   0.0%     392    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Equatable.swift
   0.0%     380   0.0%     380    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/ArrayExtensions.swift
   0.0%     380   0.0%     380    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/Core/StoreSubscriber.swift
   0.0%     372   0.0%     372    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/RegistrationToken.swift
   0.0%     352   0.0%     352    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/UserDefaultExtensions.swift
   0.0%     324   0.0%     324    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/RegistrationToken.swift
   0.0%     284   0.0%     284    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/NoOpNotificationInbox.swift
   0.0%     280   0.0%     280    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Type/InAppMessage.swift
   0.0%     228   0.0%     236    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SessionManager.swift
   0.0%     204   0.0%     204    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Arithmetic.swift
   0.0%     196   0.0%     196    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Inbox/NotificationInbox.swift
   0.0%     188   0.0%     188    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/CustomerIO+Geofence.swift
   0.0%     180   0.0%     180    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Extensions/LoggerExtensions.swift
   0.0%     164   0.0%     164    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Endpoints/QueueEndpoint.swift
   0.0%     152   0.0%     152    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/Timer.swift
   0.0%     140   0.0%     140    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/Lock.swift
   0.0%     136   0.0%     136    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/CustomerIO+Location.swift
   0.0%     120   0.0%     120    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/DataExtensions.swift
   0.0%     116   0.0%     116    /Users/runner/work/customerio-ios/customerio-ios/Sources/DataPipeline/Plugins/CustomerIODestination.swift
   0.0%     116   0.0%     116    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/Config/LocationConfig.swift
   0.0%     116   0.0%     116    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/Aliases.swift
   0.0%     112   0.0%     112    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Synchronized/Synchronized+Bool.swift
   0.0%      96   0.0%      96    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/RetryDecision.swift
   0.0%      92   0.0%      92    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingPush/PushHandling/PushClickHandler.swift
   0.0%      84   0.0%      84    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/DownloadFileType.swift
   0.0%      84   0.0%      84    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceLocationMode.swift
   0.0%      84   0.0%      84    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceSyncMode.swift
   0.0%      84   0.0%      84    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/Endpoints/Utilities/GistNetworkRequestError.swift
   0.0%      84   0.0%      84    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/SseConnectionState.swift
   0.0%      68   0.0%      68    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/NetworkSettings.swift
   0.0%      48   0.0%      48    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Config/MessagingInAppConfigOptions.swift
   0.0%      36   0.0%      36    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/DateUtil.swift
   0.0%      36   0.0%      36    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/Time.swift
   0.0%      32   0.0%      32    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/DeviceMetricsGrabber.swift
   0.0%      32   0.0%      32    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Util/SingleScheduleTimer.swift
   0.0%      32   0.0%      32    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Event/GeofenceDeliveryTracker.swift
   0.0%      32   0.0%      32    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/EngineWeb/EngineWebProvider.swift
   0.0%      28   0.0%      28    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Version.swift
   0.0%      16   0.0%      16    /Users/runner/work/customerio-ios/customerio-ios/Sources/Location/ApplicationStateProvider.swift
   0.0%      16   0.0%      16    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Network/SSE/Sleeper.swift
   0.0%      16   0.0%      16    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/Gist/Utilities/ApplicationStateProvider.swift
   0.0%      12   0.0%      12    /Users/runner/work/customerio-ios/customerio-ios/Sources/MessagingInApp/State/Core/Synchronized.swift
   0.0%       8   0.0%       8    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Extensions/ErrorExtension.swift
 100.0%  1.06Mi 100.0%  1.06Mi    TOTAL

SDK binary size diff report vs. main branch
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW] +19.0Ki  [NEW] +19.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/GeofenceStorage.swift
  [NEW] +16.0Ki  [NEW] +16.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Store/BackgroundDeliveryContextStore.swift
  [NEW] +14.6Ki  [NEW] +14.7Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceSyncCoordinator.swift
  [NEW] +14.0Ki  [NEW] +14.0Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Monitor/CoreLocationGeofenceMonitor.swift
 -91.8% +11.6Ki -91.8% +11.6Ki    [41 Others]
  [NEW] +11.2Ki  [NEW] +11.2Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Event/GeofenceEventTracker.swift
  [NEW] +10.00Ki  [NEW] +10.00Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Api/GeofenceApiResponse.swift
  [NEW] +9.51Ki  [NEW] +9.51Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/PendingGeofenceMetricStore.swift
   +37% +9.12Ki   +37% +9.12Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Communication/Event.swift
  [NEW] +8.99Ki  [NEW] +8.99Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/GeofenceState.swift
  [NEW] +8.50Ki  [NEW] +8.50Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceDistanceFilter.swift
  [NEW] +7.52Ki  [NEW] +7.53Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceModuleState.swift
  [NEW] +7.32Ki  [NEW] +7.32Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Storage/PendingGeofenceMetric.swift
  [NEW] +7.13Ki  [NEW] +7.13Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/Service/BackgroundDeliveryHttpClient.swift
  [NEW] +6.48Ki  [NEW] +6.48Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceBootstrap.swift
  [NEW] +4.88Ki  [NEW] +4.88Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Model/Geofence.swift
  [NEW] +4.84Ki  [NEW] +4.84Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Coordinator/GeofenceSyncCoordinator+RefreshDecision.swift
  [NEW] +3.81Ki  [NEW] +3.81Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Api/GeofenceApiService.swift
  [NEW] +3.33Ki  [NEW] +3.33Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/GeofenceModule.swift
  [NEW] +3.27Ki  [NEW] +3.27Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/LocationGeofence/Logger+Geofence.swift
 -35.2% -6.12Ki -35.2% -6.12Ki    /Users/runner/work/customerio-ios/customerio-ios/Sources/Common/CustomerIOInstance.swift
   +19%  +174Ki   +19%  +175Ki    TOTAL

@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.31579% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.10%. Comparing base (0cdd3fe) to head (9c5a3c6).

Files with missing lines Patch % Lines
Sources/LocationGeofence/CustomerIO+Geofence.swift 0.00% 10 Missing ⚠️
Sources/Location/LocationServices.swift 85.71% 3 Missing ⚠️
Additional details and impacted files
@@                      Coverage Diff                       @@
##           feature/geofence-on-device    #1140      +/-   ##
==============================================================
+ Coverage                       71.61%   72.10%   +0.48%     
==============================================================
  Files                             247      248       +1     
  Lines                           13072    13140      +68     
==============================================================
+ Hits                             9362     9475     +113     
+ Misses                           3710     3665      -45     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Let hosts use geofencing without emitting "CIO Location Update" analytics
events or enriching identify context. Adds an internal
requestLocationUpdateSilently() that acquires a fix, posts LocationAcquired,
and records it as last-known only — no track event, no persistence, not in
identify enrichment. It runs regardless of LocationConfig.mode (geofencing
needs a fix even when tracking is off) while still requiring permission.

Splits the location cache: getLastKnownLocation() reflects any fix (incl.
silent) in-memory, while the persisted cache that feeds enrichment stays
tracking-only. Adds GeofenceLocationMode {automatic (default), manual} and
CustomerIO.geofence.refreshFromCurrentLocation().

The geofence refresh decision runs at app launch (SDK/module init), on
identify, and on a fresh location fix, gated on an identified user; in
.automatic it self-acquires a silent fix when none is available. Refreshes
anchor at the last registration center (falling back to the location cache)
so a refresh after background movement doesn't re-rank from a stale fix, and
identify no longer falsely arms the first-run rearm when an anchor exists.

Sample app drives geofencing via refreshFromCurrentLocation() after a
background permission grant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mrehan27 mrehan27 force-pushed the mbl-1978-geofence-internal-location-api branch from 4a69388 to f850c24 Compare July 2, 2026 13:13
/// Set by a host-initiated `refreshFromCurrentLocation()`. The next acquired fix drives a
/// refresh regardless of the no-location rearm flag, so a manual refresh works even when it
/// does not coincide with a first-run no-anchor skip.
private let explicitRefreshRequested = Synchronized<Bool>(false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be cleared on logout?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — added 9c5a3c6f. On ResetEvent both arming flags (explicitRefreshRequested and lastSkippedForNoLocation) are now cleared synchronously, so a previous user's pending refresh can't carry into the next session. Matches Android's onUserSignedOut.

On ResetEvent, clear explicitRefreshRequested and lastSkippedForNoLocation so a
previous user's pending refresh intent can't drive a sync for the next user.
Cleared synchronously in the observer so it lands before a re-login's identify
re-arms. Matches Android's onUserSignedOut.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mrehan27 mrehan27 changed the title chore(geofence): silent location acquisition + GeofenceLocationMode chore(geofence): acquire location without emitting analytics events Jul 3, 2026
@mrehan27 mrehan27 merged commit 38d2a39 into feature/geofence-on-device Jul 3, 2026
17 checks passed
@mrehan27 mrehan27 deleted the mbl-1978-geofence-internal-location-api branch July 3, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants