Add Static Location and Live Location Support
🔗 Issue Links
Resolves https://linear.app/stream/issue/IOS-578/location-attachment
🎯 Goal
Adds support for static and live location attachments in the Low-Level Client SDK.
The UI has been implemented in the Demo App to demonstrate how to use the new location APIs.
📝 Summary
New APIs:
ChatChannelControllersendStaticLocation()- Sends a static location message to the channel.startLiveLocationSharing()- Starts a live location-sharing message in the channel.
ChatMessageControllerpartialUpdateMessage()- Updates the message partially. (It was missing from the SDK)stopLiveLocationSharing()- Stops sharing the live location attachment if it has one.
CurrentChatUserControllerupdateLiveLocation()- Updates the location of all active live location messages for the current user.loadActiveLiveLocationMessages()- Loads all active locations of the current user. Should be called only once.
CurrentChatUserControllerDelegatedidStartSharingLiveLocation()- Notifies whenever the current user is sharing any live location.didStopSharingLiveLocation()- Notifies whenever the current user stopped/expired all live locations.didChangeActiveLiveLocationMessages()- Notifies whenever the current user's live location messages change.didFailToUpdateLiveLocation()- Called whenever a live location failed to update. Mostly should be used for debugging.
Throttler- The Throttler was part of the UI SDK somehow, so it was moved to the LLC and made public like the Debouncer.
ChatMessagesharedLocation- Returns the location if it has one, either live or static.
🛠 Implementation
The SDK at the moment only handles updating the location attachments. The location tracking should be provided by the App. Something like the LocationProvider in the Demo App should be implemented by the customer.
Creating a location attachment
In order to create a new message with a location attachment, the developer can use the ChannelController.sendStaticLocation() or the ChannelController.startSharingLiveLocation().
Sending location updates (Live Location)
The customer is responsible for sending new location updates to the SDK. This is done through the CurrentChatUserController.updateLiveLocation() method. This method will update all the current user's active location attachments. Internally, it uses a activeLiveLocationMessagesObserver that keeps track of the active location attachments of the current user. These changes are also available to the customer through the CurrentChatUserControllerDelegate to make it easier for the developer to know when it should track location updates and when it can turn them off.
Stopping live location attachment
ChatMessageController.stopLiveLocationSharing(): Stops a live location attachment in the given message if it has an active location attachment.
Overall Data Flow
sequenceDiagram
participant App
participant LocationProvider
participant SDK
participant Backend
Note over App,Backend: Start New Location Share
App->>LocationProvider: getCurrentLocation()
LocationProvider-->>App: Return current location
App->>SDK: startLiveLocationSharing(location)
SDK->>Backend: Create location message
Backend-->>SDK: Confirm creation
SDK->>App: onStartLiveLocationSharing()
App->>LocationProvider: startMonitoring()
Note over App,Backend: Location Updates
LocationProvider->>LocationProvider: Monitor location changes
LocationProvider->>SDK: didUpdateLocation(location)
SDK->>Backend: updateLiveLocation
Note over SDK: 3s Throttling
Note over App,Backend: Stop Location Share
App->>SDK: stopLiveLocationSharing()
SDK->>Backend: Stop location sharing
Backend-->>SDK: Confirm stop
SDK->>App: onStopLiveLocationSharing()
App->>LocationProvider: stopMonitoring()
🎨 Showcase
| Static | Live |
|---|---|
🧪 Manual Testing Notes
Note: To simulate live location updates in the Simulator, with the Simulator selected, Go to Features > Location > City Bicycle Ride in the top bar of the Mac.
Precondition: Select the Frankfurt C2 environemnt to test the location feature.
Send a static location message ✅
- Open a channel with location sharing enabled
- Tap on the Attachments Icon
- Tap "Send Current Location"
- It should render an image snapshot of a map with a Pin
- Tapping the attachment should open the map full screen with the Pin
Send a live location message ✅
- Open a channel with location sharing enabled
- Tap on the Attachments Icon
- Tap "Share Live Location"
- Set an end time
- It should render an image of the map with the avatar of the user in it and a button saying “Stop Sharing”
- The map is just a static image (Does not update live)
- Tapping the attachment should open the map with the user's avatar, and the user's avatar should move when the location updates.
- Tapping the "Stop Sharing" button should stop sharing the live location.
- It should update the UI, and a label with “Live location ended” appears.
- In the full-screen map view, the avatar should not move anymore.
Receiving a live location message ✅
- Share a live location attachment from another user
- The receiving user should see the location message with “Live until XXX” date.
- Once the location has reached the end, it should update the message with “Live location ended”
- The same behaviour should happen if the user is in the full-screen map view.
- In the full-screen map view, the avatar should not move anymore.
Send a live location message when one from the current user is already active ✅
- Open a channel with location sharing enabled
- Tap on the Attachments Icon
- Tap "Share Live Location"
- Set an end time
- It should render an image of the map with the avatar of the user in it and a button saying “Stop Sharing”
- Send another live location
- The new live location message should be sent, and the previous one should stop.
Active live location is ended when the last update is after expiration ✅
- Share a live location attachment with a 1-minute expiration
- The user keeps updating the location
- When the last update has already passed the expiration, it should update to “Live location ended”
- The same should happen in the full-screen map view.
Active live location is ended after the expiration is reached ✅
- Share a live location attachment with a 1-minute expiration
- The user is still, so no location updates are being sent to the server
- When the 1-minute is reached, the UI should update to “Live Location Ended”
- The same should happen in the full-screen map view.
- The location monitoring should also be stopped
Active live location from another user ends after the expiration is reached ✅
- Share a live location attachment with a 1-minute expiration with User A
- User B receive the live location in the message list.
- User A is still, so no location updates are being sent to the server
- When the 1-minute is reached, the UI from User B should update to “Live Location Ended” ❌
- The same should happen in the full-screen map view. ❌
☑️ Contributor Checklist
- [x] I have signed the Stream CLA (required)
- [x] This change should be manually QAed
- [x] Changelog is updated with client-facing changes
- [ ] Changelog is updated with new localization keys
- [x] New code is covered by unit tests
- [x] Comparison screenshots added for visual changes
- [ ] Affected documentation updated (docusaurus, tutorial, CMS)
Summary by CodeRabbit
Summary by CodeRabbit
-
New Features
- Introduced comprehensive location sharing support, including static and live location sharing in chat messages.
- Added the ability to send, update, and stop live location sharing within chat channels.
- Enhanced message and channel models to display and manage shared locations.
- New UI components for viewing and controlling shared locations, including live status indicators, map previews, user annotations, and a control banner.
- Added partial message update functionality for selective content and attachment updates.
- Added delegate callbacks and controller methods for live location lifecycle events.
- Added a location provider to manage device location services and permissions.
- Added background worker to track active live location end times and update states accordingly.
-
Improvements
- Updated privacy settings and permissions to support location access and background location updates.
- Expanded channel capabilities to indicate and control location sharing permissions.
- Enhanced message actions to disable editing for location messages.
- Improved UI handling for location attachments and live location sharing controls.
- Added throttling to live location updates to optimize network usage.
- Refined snapshot caching and UI updates for location previews.
- Reorganized and extended app configuration and plist for location sharing.
-
Bug Fixes
- Improved handling and filtering of live location messages to ensure accurate state and error reporting.
-
Tests
- Added extensive test coverage for location sharing, partial message updates, database persistence, API interactions, and error handling.
- Added tests for live location lifecycle, end time tracking, and message update scenarios.
-
Chores
- Updated documentation, changelogs, configuration files, and test data to reflect new location sharing features and permissions.
SDK Size
title |
develop |
branch |
diff |
status |
|---|---|---|---|---|
| StreamChat | 7.55 MB | 7.87 MB | +327 KB | 🟡 |
| StreamChatUI | 4.78 MB | 4.84 MB | +64 KB | 🟢 |
Quality Gate passed
Issues
190 New issues
0 Accepted issues
Measures
0 Security Hotspots
83.4% Coverage on New Code
0.4% Duplication on New Code
Walkthrough
This change introduces comprehensive location sharing support to the StreamChat iOS SDK and DemoApp. It adds static and live location sharing features, including new models, API endpoints, database entities, and UI components. The update also modifies controllers, repositories, and test suites to support sending, updating, and displaying location messages, as well as managing live location sharing lifecycles.
Changes
| File(s) / Group | Change Summary |
|---|---|
CHANGELOG.md |
Documents new location sharing features and related API additions. |
DemoApp/Info.plist |
Adds location usage descriptions, background location mode, and reorganizes privacy keys. |
DemoApp/LocationProvider.swift |
Adds a singleton for managing location permissions and updates. |
DemoApp/Screens/* |
Enables location attachments by default; integrates live location sharing lifecycle into tab bar controller. |
DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/* |
Removes old location attachment payloads; refactors and extends UI for live/static location display, adds user annotation and status views, and updates tap handling for new location model. |
DemoApp/StreamChat/Components/CustomAttachments/* |
Updates attachment view logic to use new location model; disables editing for location messages; adds channel list subtitle for location messages. |
DemoApp/StreamChat/StreamChatWrapper+DemoApp.swift |
Removes old location attachment injector registration. |
Sources/StreamChat/APIClient/Endpoints/* |
Adds endpoints and payloads for location sharing; supports partial message updates and live location management. |
Sources/StreamChat/Controllers/* |
Adds methods for sending static/live location, updating, and stopping live location sharing; expands delegate protocols for location events. |
Sources/StreamChat/Database/DTOs/*, StreamChatModel.xcdatamodeld |
Adds new Core Data entities and relationships for shared locations; supports storing, fetching, and converting live location data. |
Sources/StreamChat/Models/* |
Introduces LocationInfo, SharedLocation, and NewLocationInfo structs; extends ChatMessage and ChatChannel for location support. |
Sources/StreamChat/Repositories/MessageRepository.swift |
Adds method to fetch current user's active live location messages. |
Sources/StreamChat/Utils/Throttler.swift |
Makes throttler public for external use. |
Sources/StreamChat/Workers/* |
Adds live location update/stop logic and partial message update support. |
TestTools/StreamChatTestTools/* |
Updates mocks, dummies, and test data to support new location fields and APIs. |
Tests/StreamChatTests/* |
Adds extensive tests for location sharing features, including controller, repository, database, and API endpoint coverage. |
StreamChat.xcodeproj/project.pbxproj |
Removes old location files, adds new ones, and updates project structure for location features. |
Sequence Diagram(s)
sequenceDiagram
participant User
participant DemoApp
participant LocationProvider
participant ChatChannelController
participant StreamChat API
participant Database
User->>DemoApp: Tap "Send Location"
DemoApp->>LocationProvider: getCurrentLocation()
LocationProvider-->>DemoApp: CLLocation
DemoApp->>ChatChannelController: sendStaticLocation(location, ...)
ChatChannelController->>StreamChat API: POST /messages with location
StreamChat API-->>ChatChannelController: Message with location
ChatChannelController->>Database: Save message with location
Database-->>DemoApp: Updated message list
DemoApp-->>User: Show location message in chat
sequenceDiagram
participant User
participant DemoApp
participant LocationProvider
participant CurrentChatUserController
participant ChatChannelController
participant StreamChat API
participant Database
User->>DemoApp: Tap "Share Live Location"
DemoApp->>LocationProvider: getCurrentLocation()
LocationProvider-->>DemoApp: CLLocation
DemoApp->>ChatChannelController: startLiveLocationSharing(location, endDate, ...)
ChatChannelController->>StreamChat API: POST /messages with live location
StreamChat API-->>ChatChannelController: Message with live location
ChatChannelController->>Database: Save live location message
DemoApp->>CurrentChatUserController: loadActiveLiveLocationMessages()
CurrentChatUserController->>StreamChat API: GET /users/live_locations
StreamChat API-->>CurrentChatUserController: Active live locations
CurrentChatUserController->>Database: Save active live locations
LocationProvider->>CurrentChatUserController: on location update
CurrentChatUserController->>StreamChat API: PUT /users/live_locations (update)
StreamChat API-->>CurrentChatUserController: Updated location
CurrentChatUserController->>Database: Update location message
DemoApp-->>User: Show live location updates in chat
Assessment against linked issues
| Objective | Addressed | Explanation |
|---|---|---|
| Implement location attachment and sharing (IOS-578) | ✅ | |
| Support static and live location sharing, including sending, updating, and stopping sharing (IOS-578) | ✅ | |
| Add new models, endpoints, database entities, and UI for location features (IOS-578) | ✅ | |
| Provide delegate callbacks and error handling for location sharing lifecycle (IOS-578) | ✅ |
Assessment against linked issues: Out-of-scope changes
| Code Change | Explanation |
|---|---|
| None found |
Suggested reviewers
- martinmitrevski
- laevandus
Poem
A bunny hopped in with a map in its paw,
Sharing its location, without a flaw!
Now live or static, your whereabouts gleam,
In chat bubbles bright, on every team.
With code so robust, and tests that delight,
This rabbit says: “Location sharing’s out of sight!”
🗺️🐇✨
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
🪧 Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
I pushed a fix in commit <commit_id>, please review it.Explain this complex logic.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. Examples:@coderabbitai explain this code block.@coderabbitai modularize this function.
- PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.@coderabbitai read src/utils.ts and explain its main purpose.@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.@coderabbitai help me debug CodeRabbit configuration file.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.
CodeRabbit Commands (Invoked using PR comments)
@coderabbitai pauseto pause the reviews on a PR.@coderabbitai resumeto resume the paused reviews.@coderabbitai reviewto trigger an incremental review. This is useful when automatic reviews are disabled for the repository.@coderabbitai full reviewto do a full review from scratch and review all the files again.@coderabbitai summaryto regenerate the summary of the PR.@coderabbitai generate docstringsto generate docstrings for this PR.@coderabbitai generate sequence diagramto generate a sequence diagram of the changes in this PR.@coderabbitai resolveresolve all the CodeRabbit review comments.@coderabbitai configurationto show the current CodeRabbit configuration for the repository.@coderabbitai helpto get help.
Other keywords and placeholders
- Add
@coderabbitai ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Documentation and Community
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.
Quality Gate passed
Issues
20 New issues
0 Accepted issues
Measures
0 Security Hotspots
83.2% Coverage on New Code
0.1% Duplication on New Code