Swift 在自定义发布服务器中使用领域时,未能demangle见证错误
我以前从未遇到过见证表错误,但这是我第一次尝试测试定制发布服务器,如果我猜的话,我怀疑基于见证名称的损坏程度,线程处理有一些奇怪和奇妙的地方。在这里完全出海,所以一个指针(或多个指针!)将非常感谢 自定义发布服务器Swift 在自定义发布服务器中使用领域时,未能demangle见证错误,swift,realm,combine,Swift,Realm,Combine,我以前从未遇到过见证表错误,但这是我第一次尝试测试定制发布服务器,如果我猜的话,我怀疑基于见证名称的损坏程度,线程处理有一些奇怪和奇妙的地方。在这里完全出海,所以一个指针(或多个指针!)将非常感谢 自定义发布服务器 // MARK: Custom publisher - produces a stream of Object arrays in response to change notifcations on a given Realm collection extension Publis
// MARK: Custom publisher - produces a stream of Object arrays in response to change notifcations on a given Realm collection
extension Publishers {
struct Realm<Collection: RealmCollection>: Publisher {
typealias Output = Array<Collection.Element>
typealias Failure = Never // TODO: Not true but deal with this later
let collection: Collection
init(collection: Collection) {
self.collection = collection
}
func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
let subscription = RealmSubscription(subscriber: subscriber, collection: collection)
subscriber.receive(subscription: subscription)
}
}
}
// MARK: Convenience accessor function to the custom publisher
extension Publishers {
static func realm<Collection: RealmCollection>(collection: Collection) -> Publishers.Realm<Collection> {
return Publishers.Realm(collection: collection)
}
}
// MARK: Custom subscription
private final class RealmSubscription<S: Subscriber, Collection: RealmCollection>: Subscription where S.Input == Array<Collection.Element> {
private var subscriber: S?
private let collection: Collection
private var notificationToken: NotificationToken?
init(subscriber: S, collection: Collection) {
self.subscriber = subscriber
self.collection = collection
self.notificationToken = collection.observe { (changes: RealmCollectionChange) in
switch changes {
case .initial:
// Results are now populated and can be accessed without blocking the UI
print("Initial")
let _ = subscriber.receive(Array(collection.elements)) // ERROR THROWN HERE
// case .update(_, let deletions, let insertions, let modifications):
case .update(_, _, _, _):
print("Updated")
let _ = subscriber.receive(Array(collection.elements))
case .error(let error):
fatalError("\(error)")
#warning("Impl error handling - do we want to fail or log and recover?")
}
}
}
func request(_ demand: Subscribers.Demand) {
// no impl as RealmSubscriber is effectively just a sink
}
func cancel() {
print("Cancel called on RealnSubscription")
subscriber = nil
notificationToken = nil
}
}
想法?这是一个转移视线的问题,但与联合有关,而是一些快速构建问题,尝试切换到迦太基,而不是使用SPM来查看问题是否消失
对于其他人来说,这个链接可能听起来像是在转移注意力,这真的与联合收割机有关吗?错误消息与联合收割机无关。你看了吗?谢谢你的建议。碰巧我正在使用SwiftPM,正如在本文中一样,关闭“死代码剪切”确实解决了这个问题。然而,因为我不了解这个过程,我不确定这是否会在以后引起问题(除了可能扩大我的应用程序的大小)。我将发布关于这个主题的另一个问题…实际上我说得太快了!即使关闭了死代码剪切,当我添加另一个测试用例时,错误也会再次出现。。。。我将删除SwiftPM包,并查看错误是否仍然存在于Carthage.OK-切换到Carthage,问题就会消失。因此,看来SwiftPM和/或Realm与依赖关系管理器的集成是罪魁祸首。请你回答这个问题@Sajjon好让我给你打勾吗?:-)完成,在回答中写了一些简短的总结
protocol RealmServiceType {
func all<Element>(_ type: Element.Type, within realm: Realm) -> AnyPublisher<Array<Element>, Never> where Element: Object
@discardableResult
func addPatient(_ name: String, to realm: Realm) throws -> AnyPublisher<Patient, Never>
func deletePatient(_ patient: Patient, from realm: Realm)
}
extension RealmServiceType {
func all<Element>(_ type: Element.Type) -> AnyPublisher<Array<Element>, Never> where Element: Object {
print("Called \(#function)")
return all(type, within: try! Realm())
}
}
final class TestRealmService: RealmServiceType {
private let patients = [
Patient(name: "Tiddles"), Patient(name: "Fang"), Patient(name: "Phoebe"), Patient(name: "Snowy")
]
init() {
let realm = try! Realm()
guard realm.isEmpty else { return }
try! realm.write {
for p in patients {
realm.add(p)
}
}
}
func all<Element>(_ type: Element.Type, within realm: Realm) -> AnyPublisher<Array<Element>, Never> where Element: Object {
return Publishers.realm(collection: realm.objects(type).sorted(byKeyPath: "name")).eraseToAnyPublisher()
}
func addPatient(_ name: String, to realm: Realm) throws -> AnyPublisher<Patient, Never> {
let patient = Patient(name: name)
try! realm.write {
realm.add(patient)
}
return Just(patient).eraseToAnyPublisher()
}
func deletePatient(_ patient: Patient, from realm: Realm) {
try! realm.write {
realm.delete(patient)
}
}
}
class AthenaVSTests: XCTestCase {
private var cancellables = Set<AnyCancellable>()
private var service: RealmServiceType?
override func setUp() {
service = TestRealmService()
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
service = nil
cancellables.removeAll()
}
func testRealmPublisher() {
var outcome = [""]
let expectation = self.expectation(description: #function)
let expected = ["Tiddles", "Fang", "Phoebe", "Snowy"]
let _ = service?.all(Patient.self)
.sink(receiveCompletion: { _ in
expectation.fulfill() },
receiveValue: { value in
outcome += value.map { $0.name }
})
.store(in: &cancellables)
waitForExpectations(timeout: 2, handler: nil)
XCTAssert(outcome == expected, "Expected \(expected) Objects but got \(outcome)")
}
}
let _ = subscriber.receive(Array(collection.elements))