SendBirdCombine
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函数。例如
- 连接到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)
- 在频道上发送文本消息
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)
- 监听频道事件
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)
- 当您需要使用嵌套闭包和/或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)
- 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文件。