-
Notifications
You must be signed in to change notification settings - Fork 14
Create Geofence events #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension. |
1068203 to
9e58bb1
Compare
* Use client/geofences and add apiKey to request * Use 2025-10-15.pre api revision * Remove mock call and mock data * Fix tests * include error message in log Co-authored-by: Andrew Balmer <[email protected]> --------- Co-authored-by: Andrew Balmer <[email protected]>
ab1470
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall looks great, just some minor comments and suggested changes
ab1470
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some suggested changes regarding OSLog privacy
| } | ||
| return | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So more context about this -- it's a sensible guard to put in anyways where we would expect there to be a valid API key to use with our fetchGeofences call. But there's some weirdness where when CLLocationManager() is instantiated (which we do on launch to ensure background/terminated support) it also triggers didChangeAuthorization even if the actual auth level has not changed. This fires before initialization is able to complete, so as a result when we trigger setupGeofences because we have the correct auth level, we may not have the actual API key. This results in fetching the geofences for a nil company which returns empty which then clears any existing geofences.
tldr; we need this to make sure we can support being responsive to authorization level changes (such as if they revoke it and we need to unregister our geofences) while also carefully handling the timing issues between when CoreLocation is setting up and the app can be initialized
ajaysubra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey did a quick pass. Will look into this in more detail tomorrow.
| } | ||
|
|
||
| /// To be called in didFinishLaunchingWithOptions to ensure geofence events that happen in a backgrounded/terminated state are processed. | ||
| public func monitorGeofencesFromBackground() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we do this within our SDK instead of having the developer add this in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, from my understanding, didFinishLaunchingWithOptions is the very very very first thing called in the lifecycle when waking up an app from the terminated state. There isn't any UIApplication notification we can hook into reliably like how we have other app life cycle events that will be an equivalent catch-all for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we either hook into foregrounded life cycle event and or have something in initialize since that gets called when the app is launch and have a hook in location that observers something in KlaviyoSwift and does this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm the foregrounded life cycle event only is fired when the app is actually opened, so this wouldn't work in the terminated state. As for the initialize hook, I've been keeping geofencing methods pretty separate from it with the late initialization case in mind. (Part of that will be making KlaviyoLocation observe companyId changes and update the geofences then but unrelated to this monitorGeofencesFromBackground necessity.) But as far as I've explored, I think since we don't actually have any direct insurance to hook into didFinishLaunchingWithOptions from the SDK side, it's most assured to instruct developers to implement it themselves. Let me know if I'm misunderstanding/missing something else here
| super.init() | ||
| self.locationManager.delegate = self | ||
| self.locationManager.allowsBackgroundLocationUpdates = true | ||
| self.locationManager.startMonitoringSignificantLocationChanges() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Unconditional Background Location Causes App Crashhrase
Setting allowsBackgroundLocationUpdates = true unconditionally in the initializer will cause a runtime crash if the host app's Info.plist doesn't include "location" in the UIBackgroundModes array. This is a required configuration per Apple's documentation. The SDK initializes this singleton when monitorGeofencesFromBackground() is called (which just accesses the shared instance), meaning apps will crash immediately if they haven't configured their Info.plist properly. This property should only be set when geofencing is actively being used, or the SDK should add proper error handling and documentation about this requirement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will be part of our documentation/setup requirements so....
|
Hey @belleklaviyo while reviewing your PR, I noticed that we had the |
- Changed KlaviyoLocationManager from public to internal class - Removed redundant internal keywords from all type declarations: - KlaviyoLocationManager, KlaviyoGeofenceManager - GeofenceServiceProvider, GeofenceService - Geofence, GeofenceError - LocationManagerProtocol - Removed redundant internal keywords from all members (properties, methods, inits) - Types now rely on Swift's default internal access level for clarity All 13 tests passing.
ajaysubra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, Belle!
Description
So this does a bit more than just creating geofence events but it all makes sense together:
/client/eventsstartMonitoringSignificantLocationChangesto ensure we can monitor location events in the backgrounded and terminated statesmonitorGeofencesFromBackgroundto be put indidFinishLaunchingWithOptionsto ensure we can monitor location events in the backgrounded and terminated statesenqueueEventso if its a goefence event it automatically flushes the queue, regardless of initialization stateNotes
Due Diligence
Release/Versioning Considerations
PatchContains internal changes or backwards-compatible bug fixes.MinorContains changes to the public API.MajorContains breaking changes.Changelog / Code Overview
This updates the event metrics going to
client/eventsto the expected dimension names.Test Plan
Related Issues/Tickets
https://klaviyo.atlassian.net/browse/CHNL-25309