Swiftpack.co - Oleg-E-Bakharev/SwiftObserver as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by Oleg-E-Bakharev.
Oleg-E-Bakharev/SwiftObserver 0.1.0
Swift Observer Design Pattern
⭐️ 4
🕓 2 years ago
.package(url: "https://github.com/Oleg-E-Bakharev/SwiftObserver.git", from: "0.1.0")

SwiftObserver

Реализация шаблона проектирования Наблюдатель на Swift. Концептуально заменяет схемы применения UIControl и [NS]NotificationCenter на чистом Swift. Весь код покрыт тестами. Покрытие > 95%.

Штатный способ подключения - Swift Package Manager. https://github.com/Oleg-E-Bakharev/SwiftObserver

Если нехватает функционала доставки уведомлений на DispatchQueue обратите внимание на пакет https://github.com/Oleg-E-Bakharev/ObserverPlus

Примеры использования


import XCTest
import SwiftObserver

private protocol Subject {
    var eventVoid: Event<Void> { get }
}

private final class Emitter: Subject {
    private var voidSender = EventSender<Void>()
    var eventVoid: Event<Void> { voidSender.event }
    
    func send() {
        voidSender.send()
    }
}

private final class Receiver {
    func onVoid() {
        print("Event received")
    }
}

final class ObserverSandbox: XCTestCase {
    public func testTargetActionObserver() {
        let emitter = Emitter()
        let receiver = Receiver()
        let subject: Subject = emitter
        subject.eventVoid += Observer(target: receiver, action: Receiver.onVoid)
        emitter.send() // "Event received"
    }
    
    public func testTargetActionLinkObserver() {
        let emitter = Emitter()
        let receiver = Receiver()
        let subject: Subject = emitter
        var mayBeLink: Any?
        do {
            let link = Observer.Link(target: receiver, action: Receiver.onVoid)
            subject.eventVoid += link
            mayBeLink = link
        }
        XCTAssertNotNil(mayBeLink)
        emitter.send() // Event received
        mayBeLink = nil
        emitter.send() // No output
    }
    
    // Prmanent closure observer
    func testPermanentClosure() {
        let emitter = Emitter()
        let subject: Subject = emitter
//        subject.eventVoid += ObserverClosure<Void>() { ... }
        subject.eventVoid += { // OMG!!!
            print("Event received")
        }
        emitter.send() // Event received
    }

    // Disposable closure link
    func testCaseFour() {
        let emitter = Emitter()
        let subject: Subject = emitter
        var maybeLink: Any?
        do {
            let link = ObserverClosure.Link {
                print("Event received")
            }
            subject.eventVoid += link
            maybeLink = link
        }
        XCTAssertNotNil(maybeLink)
        emitter.send() // Event received
        maybeLink = nil
        emitter.send() // No output
    }
}

Асинхронное применение

protocol AsyncSubject {
    var eventVoid: Event<Void> { get async }
    var eventInt: Event<Int> { get async }
}

actor EmitterActor {
    private var voidSender = EventSender<Void>()
    private var intSender = EventSender<Int>()

    func sendVoid() async {
        voidSender.send()
    }

    func sendInt() async {
        intSender.send(0)
    }
}

extension EmitterActor: AsyncSubject {
    var eventVoid: Event<Void> { voidSender.event }
    var eventInt: Event<Int> { intSender.event }
}


final class ObserverAsyncTests: XCTestCase {

    func testActorEvents() async {
        let voidExp = expectation(description: "Void")
        let intExp = expectation(description: "Int")
        let e = EmitterActor()
        let s: AsyncSubject = e
        await s.eventVoid += {
            voidExp.fulfill()
        }
        await s.eventInt += { _ in
            intExp.fulfill()
        }
        await e.sendVoid()
        await e.sendInt()
        await waitForExpectations(timeout: 1)
    }

}

Примечание.

Если вы получили ошибку компиляции вида: Binary operator '+=' cannot be applied to operands of type 'Event' and '() -> ()' Значит вы забыли добавить import SwiftObserver

GitHub

link
Stars: 4
Last commit: 1 year ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics