iOS RxDelegateProxy 만들어보기 #2
iOS 인턴을 수행하고 있는데, RxStarscream이 관리가 안되어서 Starscream 기반으로 RxStarscream을 사내에서 직접 만들어서 사용하기로 함.
문제 RxStarscream의 RxSwift 버전이 4점대에 멈춰있고, 현재는 6점대로 수정한 PR도 받아주지 않는 상황이라서 오픈소스를 사용할 때는 이런 점들도 잘 고려해야겠다 싶음!
연관포스팅
- [iOS RxStarScream 총정리](https://rldd.tistory.com/271)
- [iOS Starscream 총정리](https://rldd.tistory.com/272)
- [iOS RxDelegateProxy 만들어보기 #1](https://rldd.tistory.com/273)
- [iOS RxDelegateProxy 만들어보기 #2 - StarScream + RxProxy](https://rldd.tistory.com/274)
- [Extension Reactive (RxSwift)](https://rldd.tistory.com/275)
문제상황
소켓 통신을 위해 Starscream을 사용하고 있는데 RxSwift로 사용할 수 있게 해야함.
RxStarscream이 존재하나 관리가 되지 않아 RxSwift 4점대 (현재 6점대)
Starscrem + RxProxy를 활용해 프로젝트 내부에서 사용할 수 있도록 구현해보고자 함.
문제상황
소켓 통신을 위해 Starscream을 사용하고 있는데 RxSwift로 사용할 수 있게 해야함.
RxStarscream이 존재하나 관리가 되지 않아 RxSwift 4점대 (현재 6점대)
코드 구현체
프록시로 묶어서 처리할 수 있음
import UIKit
import RxSwift
import RxCocoa
import Starscream
public enum WebSocketEvent {
case connected
case disconnected(Error?)
case message(String)
case data(Data)
case pong
}
public final class RxWebSocketDelegateProxy<Client: WebSocketClient>: DelegateProxy<Client, NSObjectProtocol>,
DelegateProxyType,
WebSocketDelegate,
WebSocketPongDelegate
{
private weak var forwardDelegate: WebSocketDelegate?
private weak var forwardPongDelegate: WebSocketPongDelegate?
fileprivate let subject = PublishSubject<WebSocketEvent>()
required public init(websocket: Client) {
super.init(parentObject: websocket, delegateProxy: RxWebSocketDelegateProxy.self)
}
public static func currentDelegate(for object: Client) -> NSObjectProtocol? {
return object.delegate as? NSObjectProtocol
}
public static func setCurrentDelegate(_ delegate: NSObjectProtocol?, to object: Client) {
object.delegate = delegate as? WebSocketDelegate
object.pongDelegate = delegate as? WebSocketPongDelegate
}
public static func registerKnownImplementations() {
self.register { RxWebSocketDelegateProxy(websocket: $0) }
}
public func websocketDidConnect(socket: WebSocketClient) {
subject.onNext(WebSocketEvent.connected)
forwardDelegate?.websocketDidConnect(socket: socket)
}
public func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
subject.onNext(WebSocketEvent.disconnected(error))
forwardDelegate?.websocketDidDisconnect(socket: socket, error: error)
}
public func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
subject.onNext(WebSocketEvent.message(text))
forwardDelegate?.websocketDidReceiveMessage(socket: socket, text: text)
}
public func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
subject.onNext(WebSocketEvent.data(data))
forwardDelegate?.websocketDidReceiveData(socket: socket, data: data)
}
public func websocketDidReceivePong(socket: WebSocketClient, data: Data?) {
subject.onNext(WebSocketEvent.pong)
forwardPongDelegate?.websocketDidReceivePong(socket: socket, data: data)
}
deinit {
subject.onCompleted()
}
}
extension Reactive where Base: WebSocketClient {
public var response: Observable<WebSocketEvent> {
return RxWebSocketDelegateProxy.proxy(for: base).subject
}
public var text: Observable<String> {
return self.response
.filter {
switch $0 {
case .message:
return true
default:
return false
}
}
.map {
switch $0 {
case .message(let message):
return message
default:
return String()
}
}
}
public var connected: Observable<Bool> {
return response
.filter {
switch $0 {
case .connected, .disconnected:
return true
default:
return false
}
}
.map {
switch $0 {
case .connected:
return true
default:
return false
}
}
}
public func write(data: Data) -> Observable<Void> {
return Observable.create { sub in
self.base.write(data: data) {
sub.onNext(())
sub.onCompleted()
}
return Disposables.create()
}
}
public func write(ping: Data) -> Observable<Void> {
return Observable.create { sub in
self.base.write(ping: ping) {
sub.onNext(())
sub.onCompleted()
}
return Disposables.create()
}
}
public func write(string: String) -> Observable<Void> {
return Observable.create { sub in
self.base.write(string: string) {
sub.onNext(())
sub.onCompleted()
}
return Disposables.create()
}
}
}
'project > 개발 업무' 카테고리의 다른 글
SwiftUI로 Placeholder가 존재하는 TextField 설계 팁 (UIKit호환) (1) | 2024.09.29 |
---|---|
[Xcode 16 Beta] Could not download and install iOS 18.0 Simulator runtime with Xcode 16.0 beta (0) | 2024.06.12 |
[XCode 15.0 beta] Preview Macro Bug (0) | 2023.06.08 |
Lottie 리소스 문제로 앱이 초기화되는 현상 (0) | 2022.07.12 |
iOS 공유하기 LPLinkMetadata (UIKit, SwiftUI) 디자인패턴 적용 (0) | 2021.06.07 |