SendBirdCombine 1.1.0

SendBirdCombine 1.1.0

David Rajan 维护。



  • David Rajan

SendBirdCombine

Version License Platform

SendBirdCombine 是一个 Swift 框架,它为 Combine 提供了对 SendBird SDK 的扩展。注:本项目与 Sendbird, Inc. 无关。SendBird 是一个提供基于 Objective-C 的 iOS SDK 的短信平台,并使用一些较旧的设计模式,如基于代理的回调。 SendBirdCombine 努力为 SendBird SDK 提供一个使用 Combine 的现代响应式接口,让您编写和维护代码变得更加简单。

兼容性

SendBirdCombine 需要 iOS 13+ 并与 Swift 5 项目兼容。

安装

SendBirdCombine 通过 CocoaPods 提供使用。要安装它,只需将以下行添加到您的 Podfile 中

pod 'SendBirdCombine'

SendBirdCombine 还提供了对 SendBird Calls 的支持。由于 SendBirdCalls SDK 的二进制文件很大,因此默认情况下不包括此功能,但如果您希望包含它,请将此行添加到您的 Podfile 中,这将为您提供基本的短信功能以及通话功能支持

pod 'SendBirdCombine/Calls'

使用方法

SendBirdCombine为支持SendBird的即时通讯应用提供了Combine发布者。您可以选择订阅这些发布者而不是使用默认的SendBird API函数。例如

  1. 连接到SendBird实例
var subscriptions = Set<AnyCancellable>()
...
SBDMain.connect(userId: "sendbirdUserId")
    .sink(receiveCompletion: { completion in
        switch completion {
        case let .failure(error):
            print("Sendbird connection error: \(error)")
        case .finished:
            // do something here after connection call completes
        }
    }, receiveValue: { user in
        // do something here after receiving connected SendBird `SBDUser` object
    })
    .store(in: &subscriptions)
  1. 在频道上发送文本消息
channel.sendUserMessage("message to send")
    .sink(receiveCompletion: { completion in
        switch completion {
        case let .failure(.generalFailure(error)):
            print("error creating message: \(error)")
        case let .failure(.sendingFailed(message, error)):
            print("error sending message: ", message.messageId, error")
        case .finished:
            // handle successful completion
        }
    }, receiveValue: { status in
        switch status {
        case let .tempMessage(message):
            // handle received temporary placeholder message returned by SendBird
        case let .sentMessage(message):
            // handle successfully sent message returned from SendBird
        default:
            // handle any other type of event here
        }
    })
    .store(in: &subscriptions)
  1. 监听频道事件
channel.eventPublisher
    .sink { event in
        switch event {
        case let .received(message):
            // handle received message in this channel
        case let .messageDeleted(messageId):
            // handle deleted message with messageId in this channel
        case let .userJoined(user):
            // handle user that joined this channel
            ...
        default:
            // handle all other cases we don't currently care about here
        }
    }
    .store(in: &subscriptions)
  1. 当您需要使用嵌套闭包和/或DispatchGroups来完成多个操作时,使用Combine的优势将更加明显。例如,为了通过URL加入开放频道,然后同时加入获取到的频道并下载其元数据(不使用Combine的情况下,代码可能如下所示)
SBDOpenChannel.getWithUrl("channelUrl") { (channel, error) in
    var enteredChannel: Bool = false
    var channelMetadata: [String: NSObject]?

    guard let channel = channel, error == nil else {
        if let error = error {
            print("error getting channel: \(error)")
            return
        } else {
            fatalError("error can't be nil")
        }
    }

    let group = DispatchGroup()

    group.enter()
    channel.enter { (error) in
        guard error == nil else {
            if let error = error {
                print("error entering channel: \(error)")
                group.leave()
                return
            } else {
                fatalError("error can't be nil")
            }
        }
        enteredChannel = true
        group.leave()
    }

    group.enter()
    channel.getAllMetaData { (metadata, error) in
        guard let metadata = metadata, error == nil else {
            if let error = error {
                print("error retrieving metadata: \(error)")
                group.leave()
                return
            } else {
                fatalError("error can't be nil")
            }
        }

        channelMetadata = metadata
        group.leave()
    }

    group.notify(queue: .main) {
        guard enteredChannel == true, let metadata = channelMetadata else {
            print("error entering channel and/or retrieving metadata")
            return
        }

        print("entered channel and got metadata: \(metadata)")
    }
}

但是当您在Combine中链式调用这些操作时,代码将变得更加简洁和易于阅读

SBDOpenChannel.getWithUrl("channelUrl")
    .flatMap { channel in
        channel.enter().zip(channel.getAllMetaData())
    }
    .sink(receiveCompletion: { (completion) in
        switch completion {
        case .failure(let error):
            print("error: \(error)")
        case .finished:
            print("completed")
        }
    }, receiveValue: { (_, metadata) in
        print("joined and got metadata: \(metadata)")
    })
    .store(in: &subscriptions)
  1. SendBirdCalls也可以使用Combine处理(确保包含上面提到的高亮显示的SendBirdCombine/Calls Pod)
// Receiving a call
SendBirdCall.eventPublisher
    .sink { [weak self] event in
        // There is currently the only case handled by SendBirdCallDelegate
        guard case .startedRinging(let call) = event else { fatalError() }

        // Accept the call then handle additional events for the duration of the call
        call.accept(with: AcceptParams(callOptions: CallOptions()))
        self?.handle(call: call)
    }
    .store(in: &subscriptions)

// Dialing a call
SendBirdCall.dial(with: DialParams(calleeId: "calleeId"))
    .sink(receiveCompletion: { error in
        switch error {
        case .failure(let error):
            print("error dialing: \(error)")
        case .finished:
            // handle successful completion
        }

    }, receiveValue: { [weak self] call in
        self?.handle(call: call)
    })
    .store(in: &subscriptions)

// Listens for call events
func handle(call: DirectCall) {
    call.eventPublisher
        .sink { event in
            switch event {
            case .connected:
                // handle call connected event
            case .ended:
                // handle call ended event
                ...
            default:
                // handle additional cases
            }
    }
    .store(in: &subscriptions)
}

还有许多其他SendBird SDK函数提供有Combine发布者,请探索SendBirdCombine代码库以查看所有内容!

作者

David Rajan, [email protected]

许可协议

SendBirdCombine可在MIT许可协议下使用。有关更多信息,请参阅LICENSE文件。