Skip to content
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

Flexible Sync V2 (Proposed 1) #7755

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

dianaafanador3
Copy link
Collaborator

@dianaafanador3 dianaafanador3 commented Apr 21, 2022

This PR contains a complete new API for Flexible Sync, intended to make flexible sync less confusing to the developer.

let app = App(id: "my-app-id")
let user = try await app.login(credentials: .anonymous)
let realm = try user.realm(configuration: .defaultConfiguration)

// You can subscribe and get `QueryResults` from 1-12 queries at the same time, this subscriptions will be done within a batch write
let (persons, dogs, birds) = try await realm.subscriptions.subscribe(to: 
QuerySubscription<Person> { $0.age >= 18}, 
QuerySubscription<Dog>(), //Intended to query all elements for this object 
QuerySubscription<Bird> { $0.species == .magpie })

print(persons.count) //20

let newPerson = Person()
newPerson.age = 18
try realm.write {
    realm.add(newPerson)
}

// QueryResults will be updated if the values are within the subscription query 
print(persons.count) //21 

// Unsubscribe will remove the values from the `QueryResult` and remove the subscription from the subscription set.
try await persons.unsubscribe()

// Reusing a `QueryResults` is as easy as calling again subscribe for the same query
let persons: QueryResults<Person>= try await realm.subscriptions.subscribe(to: { $0.age >= 18 })
// Or search in your subscription set
let foundedSubscription = realm.subscriptions.first(ofType: SwiftPerson.self, where: { { $0.age >= 18 })

// You can use unsubscribeAll to remove all subscriptions from the subscription set
try await realm.subscriptions.unsubscribeAll()

// Or you can remove them by type
try await realm.subscriptions.unsubscribeAll(ofType: Person.self)

SwiftUI
You can use @ObservedResults to add a subscription and retrieve data from it
We are adding a new property to @ObservedResultswhich includes a state value, this state will publish any subscription state changes to view.

public enum SubscriptionState {
    case pending //Subscription has been added and waiting for data to bootstrap.
    case error(Error) // An error has occurred while adding the subscription (client or server side)
    case completed // Data has been bootstrapped and query results updated.
}
@available(macOS 12.0, *)
struct ObservedQueryResultsStateView: View {
    @ObservedResults(Person.self, where: { $0.age > 18 && $0.firstName == ProcessInfo.processInfo.environment["firstName"]! })
    var persons

    var body: some View {
        VStack {
            switch $persons.state {
            case .pending:
                ProgressView()
            case .completed:
                List {
                    ForEach(persons) { person in
                        Text("\(person.firstName)")
                    }
                }
            case .error(let error):
                ErrorView(error: error)
                    .background(Color.red)
                    .transition(AnyTransition.move(edge: .trailing)).animation(.default)
            }
        }
    }
}

@available(macOS 12.0, *)
struct ObservedQueryResultsView: View {
    @ObservedResults(Person.self,  where: { $0.age >= 15 && $0.firstName == ProcessInfo.processInfo.environment["firstName"]! })
    var persons
    @State var searchFilter: String = ""

    var body: some View {
        VStack {
            if persons.isEmpty {
                ProgressView()
            } else {
                List {
                    ForEach(persons) { person in
                        HStack {
                            Text("\(person.firstName)")
                            Spacer()
                            Text("\(person.age)")
                        }
                    }
                }
            }
        }
        .onDisappear {
            Task {
                do {
                    try await $persons.unsubscribe()
                }
            }
        }
    }
}

Notes

  • AnyQueryResults??, didn't add the implementation for using this as a collection, which can be added if needed but I don’t consider this to be a priority, which brings me to the issue if the user is really going to use this instead of doing a search for the query or subscribe again to the query which will retrieve the results without adding another subscription.

@cla-bot cla-bot bot added the cla: yes label Apr 21, 2022
@dianaafanador3 dianaafanador3 force-pushed the dp/flx_sync_v2_1 branch 2 times, most recently from 2430945 to 1fe61ab Compare April 22, 2022 15:28
@dianaafanador3 dianaafanador3 force-pushed the dp/flx_sync_v2_1 branch 9 times, most recently from b50f9dc to 5b4e0a0 Compare April 29, 2022 16:50
@dianaafanador3 dianaafanador3 marked this pull request as ready for review May 2, 2022 15:05
Copy link
Contributor

@leemaguire leemaguire left a comment

Choose a reason for hiding this comment

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

I like the approach this is taking. I'll play around with a sync app to test out the SwiftUI property wrappers.

RealmSwift/SyncSubscription.swift Outdated Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Outdated Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Outdated Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Outdated Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Outdated Show resolved Hide resolved
RealmSwift/SyncSubscription.swift Show resolved Hide resolved
@dianaafanador3 dianaafanador3 force-pushed the dp/flx_sync_v2_1 branch 3 times, most recently from 32dd8ad to 67340af Compare June 14, 2022 15:56
@dianaafanador3 dianaafanador3 linked an issue Jun 15, 2022 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flexible Sync V2 API (1)
3 participants