Swift 访问远程用户';s realm已确认,但未执行RealmCollectionChange块-使用重新编程代码

Swift 访问远程用户';s realm已确认,但未执行RealmCollectionChange块-使用重新编程代码,swift,realm,xctest,Swift,Realm,Xctest,我试图在两个SyncUser之间交换权限,让他们从彼此的领域读取对象 我希望在正确应用权限并确认对对方用户领域的访问后,调用realm.objects(Object.Type).observe{changes in…}应该提供该用户的对象 但是RealmCollectionChange的块永远不会执行 编辑,包括SyncPermissionTest.swift的完整代码 // //同步许可测试 //领域同步权限测试 // //由Eric Lightfoot于2019年10月31日创作。 //版

我试图在两个SyncUser之间交换权限,让他们从彼此的领域读取对象

我希望在正确应用权限并确认对对方用户领域的访问后,调用
realm.objects(Object.Type).observe{changes in…}
应该提供该用户的对象

但是RealmCollectionChange的块永远不会执行

编辑,包括SyncPermissionTest.swift的完整代码

//
//同步许可测试
//领域同步权限测试
//
//由Eric Lightfoot于2019年10月31日创作。
//版权所有©2019 Homatkotech。版权所有。
//
进口基金会
导入测试
导入RealmSwift
让ROSHost=”“//排除“https://”和“realms://”
让realmName=“synctest”
让userAName:String=“User22”
让userBName:String=“User23”
var userAId:String=“”
var userBId:String=“”
类SyncPermissionTest:XctTestCase{
var userA:SyncUser!
var userB:SyncUser!
var realmA:王国!
var realmB:Realm!
覆盖函数设置(){
super.setUp()
}
func Testerything(){
打印(“注册新用户”)
注册者()
打印(“创建新领域”)
createRealms()
打印(“创建新对象”)
addSomeObjects()
打印(“读取某些对象”)
ReadUserSowNoObjects()
打印(“还不能访问其他用户的领域”)
ConnectotherUsersRealmShouldWork()连接件
打印(“现在尝试交换相互许可”)
ExchangePermissionToReadeachhersRealms()
打印(“现在再次尝试访问对方的领域”)
ConnectotherUsersRealmShouldNowWork()连接器
打印(“读取其他用户的领域”)
readOtherUsersObjects()
}
函数注册器(){
让exp\u userACreated=xctestexpection(说明:“\(userAName)已注册”)
让exp\u userBCreated=xctestexpection(说明:“\(userBName)已注册”)
让authURL=URL(字符串:“https://\(ROSHost)”)!
让userAcreds=SyncCredentials.usernamePassword(用户名:userAName,密码:userAName,注册表:true)
让userBcreds=SyncCredentials.usernamePassword(用户名:userBName,密码:userBName,注册表:true)
SyncUser.logIn(使用:userAcreds,服务器:authURL){user,出错
xctasert(err==nil)
xctasert(用户!=nil)
self.userA=用户!
userAId=user!.identity!
打印(“已创建\(用户名称)”)
exp_userACreated.fulfill()
}
SyncUser.logIn(使用:userBcreds,服务器:authURL){user,出错
xctasert(err==nil)
xctasert(用户!=nil)
self.userB=用户!
userBId=user!.identity!
打印(“已创建\(userBName)”)
exp_userBCreated.fulfill()
}
等待(等待:[exp\u userACreated,exp\u userBCreated],超时:60)
}
func createRealms(){
让exp_realmForUserACreated=xctestexpection(说明:“用户创建了一个领域”)
让exp_realmForUserBCreated=xctestexpection(说明:“用户B领域已创建”)
让realmURL=URL(字符串:“realms://\(ROSHost)/~//\(realmName)”!
var userAConfig=self.userA.configuration(realmURL:realmURL,fullSynchronization:true)
userAConfig.objectTypes=[Thing.self]
asyncOpen(配置:userAConfig){Realm,错误在
xctasert(err==nil)
打印(\(userAName.realm已创建)
self.realmA=realm
exp_realmForUserACreated.fulfill()
}
var userBConfig=self.userB.configuration(realmURL:realmURL,fullSynchronization:true)
userBConfig.objectTypes=[Thing.self]
asyncOpen(配置:userBConfig){Realm,错误在
xctasert(err==nil)
打印(“\(userBName).realm已创建”)
self.realmB=realm
exp_realmForUserBCreated.fulfill()
}
等待(等待:[exp\u realmForUserACreated,exp\u realmForUserBCreated],超时:60)
}
func addSomeObjects(){
让名字=[“花花公子”、“男人”、“文胸”、“丁格斯”、“曼诺莉亚”、“布罗塞普”]
func createRandomObjectsInRealm(领域:领域,数量:Int){
realm.beginWrite()
一共1人……多少人{
让事物=事物(价值:[

“名称”:名称[Int.random](在:0..中,由于测试函数结束,连接立即关闭,因为我错误地使用了一个
XTestExpection
实例。

问题中应包含代码。如果链接断开,将使问题无效。请花点时间查看。当您从其他领域读取对象时,这是什么意思具体来说是什么意思?域从配置中设置的任何域读取-您是否将多个域与多个用户同步?如果是这样,您必须为每次读取重新配置域以指向不同的域-此外,您需要确保所有域调用都封装在自动释放池中。感谢您的输入。我马上就这么做。now.@Jay是的,正如您在代码中看到的,我使用不同的配置完成了几个事务。例如,我们必须先将对象写入一个域,然后才能读取它们,因此在我的例子中,我让每个用户将对象写入自己的域。在后续的事务中,配置用于本例中的“远程”或“其他”或“对方”用户。我被
@autorealese
问题弄糊涂了…文件记录在哪里?如果你有时间,请查看大量关于的问题。此外,还有一些参考资料可供你在处理领域本身的事情时使用;更改、删除等。另请看。底线是,只要存在,领域就会保留对其文件的引用要更改领域,必须断开与t的连接
//
//  SyncPermissionTest.swift
//  realm-syncpermission-testTests
//
//  Created by Eric Lightfoot on 2019-10-31.
//  Copyright © 2019 HomathkoTech. All rights reserved.
//


import Foundation
import XCTest
import RealmSwift

let ROSHost = "<<your realm host>>" // Exclude 'https://', 'realms://'
let realmName = "synctest"
let userAName: String = "User22"
let userBName: String = "User23"
var userAId: String = ""
var userBId: String = ""

class SyncPermissionTest: XCTestCase {
    var userA: SyncUser!
    var userB: SyncUser!
    var realmA: Realm!
    var realmB: Realm!

    override func setUp () {
        super.setUp()
    }

    func testEverything () {
        print("Registering new users")
        registerUsers()
        print("Creating new realms")
        createRealms()
        print("Creating new objects")
        addSomeObjects()
        print("Reading some objects")
        readUsersOwnObjects()
        print("Not able to access other user's realm yet")
        connectToOtherUsersRealmShouldntWork()
        print("Now try exchanging mutual permission")
        exchangePermissionToReadEachOthersRealms()
        print("Now try accessing each other's realm again")
        connectToOtherUsersRealmShouldNowWork()
        print("Reading other user's realm")
        readOtherUsersObjects()
    }

    func registerUsers () {
        let exp_userACreated = XCTestExpectation(description: "\(userAName) registered")
        let exp_userBCreated = XCTestExpectation(description: "\(userBName) registered")

        let authURL = URL(string: "https://\(ROSHost)")!
        let userAcreds = SyncCredentials.usernamePassword(username: userAName, password: userAName, register: true)
        let userBcreds = SyncCredentials.usernamePassword(username: userBName, password: userBName, register: true)

        SyncUser.logIn(with: userAcreds, server: authURL) { user, err in
            XCTAssert(err == nil)
            XCTAssert(user != nil)
            self.userA = user!
            userAId = user!.identity!
            print("Created \(userAName)")
            exp_userACreated.fulfill()
        }

        SyncUser.logIn(with: userBcreds, server: authURL) { user, err in
            XCTAssert(err == nil)
            XCTAssert(user != nil)
            self.userB = user!
            userBId = user!.identity!
            print("Created \(userBName)")
            exp_userBCreated.fulfill()
        }

        wait(for: [exp_userACreated, exp_userBCreated], timeout: 60)
    }

    func createRealms () {
        let exp_realmForUserACreated = XCTestExpectation(description: "User A realm created")
        let exp_realmForUserBCreated = XCTestExpectation(description: "User B realm created")

        let realmURL = URL(string: "realms://\(ROSHost)/~/\(realmName)")!

        var userAConfig = self.userA.configuration(realmURL: realmURL, fullSynchronization: true)
        userAConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userAConfig) { realm, err in
            XCTAssert(err == nil)
            print("\(userAName).realm created")
            self.realmA = realm
            exp_realmForUserACreated.fulfill()
        }

        var userBConfig = self.userB.configuration(realmURL: realmURL, fullSynchronization: true)
        userBConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userBConfig) { realm, err in
            XCTAssert(err == nil)
            print("\(userBName).realm created")
            self.realmB = realm
            exp_realmForUserBCreated.fulfill()
        }

        wait(for: [exp_realmForUserACreated, exp_realmForUserBCreated], timeout: 60)
    }

    func addSomeObjects () {
        let names = ["Dude", "Man", "Bra", "Dingus", "Mangnolia", "Broseph"]

        func createRandomObjectsInRealm(realm: Realm, howMany: Int) {
            realm.beginWrite()
            for _ in 1...howMany {
                let thing = Thing(value: [
                    "name": names[Int.random(in: 0..<names.count)],
                    "age": Int.random(in: 0...1000)
                    ])
                realm.add(thing)
            }
            do {
                try realm.commitWrite()
            } catch (let err) {
                print(err.localizedDescription)
                XCTAssert(false)
            }
        }

        createRandomObjectsInRealm(realm: self.realmA, howMany: 10)
        print("Created some objects in \(userAName)'s realm")
        createRandomObjectsInRealm(realm: self.realmB, howMany: 10)
        print("Created some objects in \(userBName)'s realm")
    }

    func readUsersOwnObjects () {
        let exp_canReadObjectsFromUserAsRealm = XCTestExpectation(description: "\(userAName)'s realm contains objects")
        let exp_canReadObjectsFromUserBsRealm = XCTestExpectation(description: "\(userBName)'s realm contains objects")

        func readObjectsFromRealm (realm: Realm, expectation: XCTestExpectation) {
            let _ = realm.objects(Thing.self).observe { π in
                switch π {
                case .initial(let results), .update(let results, _, _, _):
                    print(Array(results))
                    if results.count == 10 {
                        expectation.fulfill()
                    }
                case .error(let err):
                    print(err.localizedDescription)
                    XCTAssert(false)
                }
            }
        }

        readObjectsFromRealm(realm: self.realmA, expectation: exp_canReadObjectsFromUserAsRealm)
        print("\(userAName) reads objects from \(userAName)'s realm")
        readObjectsFromRealm(realm: self.realmB, expectation: exp_canReadObjectsFromUserBsRealm)
        print("\(userBName) reads objects from \(userBName)'s realm")
        wait(for: [exp_canReadObjectsFromUserAsRealm, exp_canReadObjectsFromUserBsRealm], timeout: 60)
    }

    func connectToOtherUsersRealmShouldntWork () {
        let exp_UserAcannotConnectToUserBsRealm = XCTestExpectation(description: "\(userAName) can't connect to \(userBName)'s realm")
        let exp_UserBcannotConnectToUserAsRealm = XCTestExpectation(description: "\(userBName) can't connect to \(userAName)'s realm")

        // Connect UserA to UserB
        let userBRealmURL = URL(string: "realms://\(ROSHost)/\(userBId)/\(realmName)")!

        var userAConfig = self.userA.configuration(realmURL: userBRealmURL, fullSynchronization: true)
        userAConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userAConfig) { realm, err in
            print(err?.localizedDescription ?? "none")
            XCTAssert(err != nil)
            exp_UserAcannotConnectToUserBsRealm.fulfill()
        }

        // Connect UserB to UserA
        let userARealmURL = URL(string: "realms://\(ROSHost)/\(userAId)/\(realmName)")!

        var userBConfig = self.userB.configuration(realmURL: userARealmURL, fullSynchronization: true)
        userBConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userBConfig) { realm, err in
            print(err?.localizedDescription ?? "none")
            XCTAssert(err != nil)
            exp_UserBcannotConnectToUserAsRealm.fulfill()
        }

        wait(for: [exp_UserAcannotConnectToUserBsRealm, exp_UserBcannotConnectToUserAsRealm], timeout: 60)
    }

    func exchangePermissionToReadEachOthersRealms () {
        let exp_UserAGivesReadPermissionToUserB = XCTestExpectation(description: "\(userAName) gives read permission to \(userBName)'s realm") // Description incorrect, changed in original code
        let exp_UserBGivesReadPermissionToUserA = XCTestExpectation(description: "\(userBName) gives read permission to \(userAName)'s realm") // Description incorrect, changed in original code

        let userARealmURLStringToGivePermissionTo = "/\(userAId)/\(realmName)"
        let permissionToA = SyncPermission(realmPath: userARealmURLStringToGivePermissionTo, identity: userBId, accessLevel: .admin)
        userA.apply(permissionToA) { err in
            print(err?.localizedDescription ?? "no error")
            XCTAssert(err == nil, "userA.apply() -> Callback received with no error")
            exp_UserAGivesReadPermissionToUserB.fulfill()
        }

        let userBRealmURLStringToGivePermissionTo = "/\(userBId)/\(realmName)"
        let permissionToB = SyncPermission(realmPath: userBRealmURLStringToGivePermissionTo, identity: userAId, accessLevel: .admin)
        userB.apply(permissionToB) { err in
            print(err?.localizedDescription ?? "no error")
            XCTAssert(err == nil, "userB.apply() -> Callback received with no error")
            exp_UserBGivesReadPermissionToUserA.fulfill()
        }

        wait(for: [exp_UserAGivesReadPermissionToUserB,exp_UserBGivesReadPermissionToUserA], timeout: 60)
    }

    func connectToOtherUsersRealmShouldNowWork () {
        let exp_UserAcanConnectToUserBsRealm = XCTestExpectation(description: "\(userAName) can now connect to \(userBName)'s realm")
        let exp_UserBcanConnectToUserAsRealm = XCTestExpectation(description: "\(userBName) can now connect to \(userAName)'s realm")

        // Connect UserA to UserB
        let userBRealmURL = URL(string: "realms://\(ROSHost)/\(userBId)/\(realmName)")!

        var userAConfig = self.userA.configuration(realmURL: userBRealmURL, fullSynchronization: true)
        userAConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userAConfig) { realm, err in
            print(err?.localizedDescription ?? "no error")
            XCTAssert(err == nil)
            exp_UserAcanConnectToUserBsRealm.fulfill()
        }

        // Connect UserB to UserA
        let userARealmURL = URL(string: "realms://\(ROSHost)/\(userAId)/\(realmName)")!

        var userBConfig = self.userB.configuration(realmURL: userARealmURL, fullSynchronization: true)
        userBConfig.objectTypes = [Thing.self]
        Realm.asyncOpen(configuration: userBConfig) { realm, err in
            print(err?.localizedDescription ?? "no error")
            XCTAssert(err == nil)
            exp_UserBcanConnectToUserAsRealm.fulfill()
        }

        wait(for: [exp_UserAcanConnectToUserBsRealm, exp_UserBcanConnectToUserAsRealm], timeout: 60)
    }

    func readOtherUsersObjects () {
        let exp_userAcanReadObjectsFromUserBsRealm = XCTestExpectation(description: "\(userAName) can see that \(userBName)'s realm contains objects")
        let exp_userBcanReadObjectsFromUserAsRealm = XCTestExpectation(description: "\(userBName) can see that \(userAName)'s realm contains objects")

        func objectsRead (byUser: SyncUser, ofUser: SyncUser, expectation: XCTestExpectation) {
            // Connect UserA to UserB
            let ofUserRealmURL = URL(string: "realms://\(ROSHost)/\(ofUser.identity!)/\(realmName)")!
            var byUserConfig = byUser.configuration(realmURL: ofUserRealmURL, fullSynchronization: true)
            byUserConfig.objectTypes = [Thing.self]
            Realm.asyncOpen(configuration: byUserConfig, callbackQueue: DispatchQueue.main) { realm, err in
                print(err?.localizedDescription ?? "no error")
                XCTAssert(err == nil)
                let _ = realm!.objects(Thing.self).observe { π in
                    switch π {
                    case .initial(let results), .update(let results, _, _, _):
                        print(Array(results))
                        if results.count == 10 {
                            expectation.fulfill()
                        }
                    case .error(let err):
                        print(err.localizedDescription)
                        XCTAssert(false)
                    }
                }
            }
        }

        objectsRead(byUser: userA, ofUser: userB, expectation: exp_userAcanReadObjectsFromUserBsRealm)
        print("\(userAName) reads objects from \(userBName)'s realm")
        objectsRead(byUser: userB, ofUser: userA, expectation: exp_userBcanReadObjectsFromUserAsRealm)
        print("\(userBName) reads objects from \(userAName)'s realm")
        wait(for: [exp_userAcanReadObjectsFromUserBsRealm, exp_userBcanReadObjectsFromUserAsRealm], timeout: 60)
    }
}

class Thing: Object {
    @objc dynamic var name: String = ""
    @objc dynamic var age: Int = 0
}