From cd34472ffced5271cd4565103f4ea86a1430884b Mon Sep 17 00:00:00 2001 From: Diana Perez Afanador Date: Wed, 16 Nov 2022 18:13:32 +0100 Subject: [PATCH] Add progress callback to asynchronous `async await` initialiser for Realm --- .../SwiftObjectServerTests.swift | 33 ++++++++++++++++++- RealmSwift/Realm.swift | 10 ++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Realm/ObjectServerTests/SwiftObjectServerTests.swift b/Realm/ObjectServerTests/SwiftObjectServerTests.swift index d967cfee15..f307be58b1 100644 --- a/Realm/ObjectServerTests/SwiftObjectServerTests.swift +++ b/Realm/ObjectServerTests/SwiftObjectServerTests.swift @@ -3061,7 +3061,6 @@ class AsyncAwaitObjectServerTests: SwiftSyncTestCase { XCTAssertEqual(realm3.objects(SwiftHugeSyncObject.self).count, 2) } - @MainActor func testAsyncOpenDownloadBehaviorAlways() async throws { // Populate the Realm on the server let user1 = try await self.app.login(credentials: basicCredentials()) @@ -3092,6 +3091,38 @@ class AsyncAwaitObjectServerTests: SwiftSyncTestCase { XCTAssertEqual(realm3.objects(SwiftHugeSyncObject.self).count, 4) } + @MainActor func testAsyncOpenWithProgressNotification() async throws { + // Populate the Realm on the server + let user1 = try await self.app.login(credentials: basicCredentials()) + let realm1 = try await Realm(configuration: user1.configuration(testName: #function)) + try realm1.write { + realm1.add(SwiftHugeSyncObject.create()) + realm1.add(SwiftHugeSyncObject.create()) + } + waitForUploads(for: realm1) + + var transferred = 0 + var transferrable = 0 + let user2 = try await app.login(credentials: .anonymous) + var ex = expectation(description: "Progresss Notification") + let realm2 = try await Realm(configuration: user2.configuration(testName: #function), + downloadBeforeOpen: .once, + progress: { progress in + XCTAssert(progress.transferredBytes >= transferred) + XCTAssert(progress.transferrableBytes >= transferrable) + transferred = progress.transferredBytes + transferrable = progress.transferrableBytes + if progress.transferredBytes > 0 && progress.isTransferComplete { + ex.fulfill() + } + }) + waitForExpectations(timeout: 10.0, handler: nil) + XCTAssert(transferred >= transferrable) + + XCTAssertEqual(realm2.objects(SwiftHugeSyncObject.self).count, 2) + realm2.syncSession?.suspend() + } + func testCallResetPasswordAsyncAwait() async throws { let email = "realm_tests_do_autoverify\(randomString(7))@\(randomString(7)).com" let password = randomString(10) diff --git a/RealmSwift/Realm.swift b/RealmSwift/Realm.swift index a633afa735..3bd0892603 100644 --- a/RealmSwift/Realm.swift +++ b/RealmSwift/Realm.swift @@ -1206,7 +1206,8 @@ extension Realm { */ @MainActor public init(configuration: Realm.Configuration = .defaultConfiguration, - downloadBeforeOpen: OpenBehavior = .never) async throws { + downloadBeforeOpen: OpenBehavior = .never, + progress block: ((SyncSession.Progress) -> Void)? = nil) async throws { var rlmRealm: RLMRealm? switch downloadBeforeOpen { case .never: @@ -1217,13 +1218,18 @@ extension Realm { } case .always: rlmRealm = try await withCheckedThrowingContinuation { continuation in - RLMRealm.asyncOpen(with: configuration.rlmConfiguration, callbackQueue: .main) { (realm, error) in + let rlmTask = RLMRealm.asyncOpen(with: configuration.rlmConfiguration, callbackQueue: .main) { (realm, error) in if let error = error { continuation.resume(with: .failure(error)) } else { continuation.resume(with: .success(realm!)) } } + if let block = block { + rlmTask.addProgressNotification(on: DispatchQueue.main) { transferred, transferrable in + block(SyncSession.Progress(transferred: transferred, transferrable: transferrable)) + } + } } } if rlmRealm == nil {