Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Stream Data to Atlas - Swift SDK

On this page

  • Overview
  • Sync Data Unidirectionally from a Client Application
  • Define an AsymmetricObject
  • Connect and Authenticate with an App Services App
  • Open a Realm
  • Create Asymmetric Objects

New in version 10.29.0.

You can use Data Ingest to stream data from the client application to a Flexible Sync-enabled Atlas App Services App.

You might want to sync data unidirectionally in IoT applications, such as a weather sensor sending data to the cloud. Data Ingest is also useful for writing other types of immutable data where you do not require conflict resolution, such as creating invoices from a retail app or logging application events.

Data Ingest is optimized to provide performance improvements for heavy client-side insert-only workloads.


You can sync data unidirectionally when that object is an AsymmetricObject. Define an AsymmetricObject by deriving from AsymmetricObject:

class WeatherSensor: AsymmetricObject {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var deviceId: String
@Persisted var temperatureInFahrenheit: Float
@Persisted var barometricPressureInHg: Float
@Persisted var windSpeedInMph: Int

For more information on how to define an AsymmetricObject, see: Define an AsymmetricObject.


To stream data from the client to your backend App, you must connect to an App Services backend and authenticate a user.

let app = App(id: INSERT_APP_ID_HERE)
do {
let user = try await login()
await openSyncedRealm(user: user)
} catch {
print("Error logging in: \(error.localizedDescription)")
func login() async throws -> User {
let user = try await app.login(credentials: .anonymous)
return user

Data Ingest is a feature of Flexible Sync, so the App you connect to must use Flexible Sync.


After you have an authenticated user, you can open a synced realm using a flexibleSyncConfiguration(). Specify the AsymmetricObject types you want to sync.

func openSyncedRealm(user: User) async {
do {
var asymmetricConfig = user.flexibleSyncConfiguration()
asymmetricConfig.objectTypes = [WeatherSensor.self]
let asymmetricRealm = try await Realm(configuration: asymmetricConfig)
await useRealm(asymmetricRealm, user)
} catch {
print("Error opening realm: \(error.localizedDescription)")

Unlike bidirectional Sync, Data Ingest does not use a Flexible Sync subscription.


Mixed Synced and Non-Synced Realms in Projects

The AsymmetricObject type is incompatible with non-synced realms. If your project uses both a synced and non-synced realm, you must explicitly pass a subset of classes in your Realm configuration to exclude the AsymmetricObject from your non-synced realm.

Automatic schema discovery means that opening a non-synced realm without specifically excluding the AsymmetricObject from the configuration can throw an error related to trying to use an incompatible object type.


Once you have an open Realm, you can create an AsymmetricObject inside a write transaction using create(_ type:, value:).

func useRealm(_ asymmetricRealm: Realm, _ user: User) async {
try! asymmetricRealm.write {
value: [ "_id": ObjectId.generate(),
"deviceId": "WX1278UIT",
"temperatureInFahrenheit": 66.7,
"barometricPressureInHg": 29.65,
"windSpeedInMph": 2

You cannot read these objects. Once created, they sync to the App Services backend and the linked Atlas database.

Atlas Device Sync completely manages the lifecycle of this data. It is maintained on the device until Data Ingest synchronization is complete, and then removed from the device.

← Record Realm Events