apple/UIKit & ReactiveX
[iOS] RxStarscream 사용법 총정리!
lgvv
2022. 1. 12. 14:22
✅ 이번 시간에는 RxStarscream에 대해서 알아볼 예정이야.
우선 RxStarscream란 무엇인지 알아봐야겠지?
https://github.com/RxSwiftCommunity/RxStarscream
RxStarScream은 위에 사이트를 가면 자세히 볼 수 있어.
WebSocket을 사용한다고 하면 주로 Starscream을 사용하는데 이걸 Rx로 제공해줘서 쉽게 사용할 수 있는 도구야.
사실 Starscream을 가지고 Proxy로 감싸서 사용할 수도 있겠지만...
이 과정이 생각보다 많이 까다로운 과정이라서 이건 나중에 따로 포스팅하도록 할게.
✅ 사전준비
1. webSocket을 사용할 수 있는 서버?
-> 저는 개인적으로 WebSocket을 사용할 수 있는 서버가 있어서 그걸 이용했습니다!
없으신 분들은 직접 찾아보셔야 해서 ㅠㅠ 흐름이라도 알고가셔요!
✅ RxStarScream.swift
import Foundation
import Starscream
import RxStarscream
import SnapKit
import Then
import RxCocoa
import RxSwift
class RxStarScream: UIViewController {
var bag = DisposeBag()
private var webSocket: WebSocket!
private var reqData: String = "{\n\"type\": \"staff\",\n\"content\": \"홍길동\"\n}" // 서버에 요청할 임시 요청 데이터
private let writeSubject = PublishSubject<String>()
private lazy var loadBtn = UIButton().then {
$0.setTitle("load Button", for: .normal)
$0.backgroundColor = .blue
}
private lazy var loadLabel = UILabel().then {
$0.text = "자 과연 여기에 값을 넣을 수 있을까요?"
$0.backgroundColor = .red
$0.textAlignment = .center
}
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setConstraints()
connect() // 1. webSocket 서버와 연결
setBinding()
}
private func setBinding() {
// 3. 버튼을 탭하면 sendMessage 함수 호출
loadBtn.rx.tap
.debug("tap")
.bind { [weak self] in
self?.sendMessage(message: self!.reqData)
}
.disposed(by: bag)
// 5. 웹 소켓을 통해 응답이 왔을때 rx로 처리하는 로직
webSocket.rx.response
.bind { [self] response in
switch response {
case .connected:
print("connected")
case .disconnected (let _):
print("DisConnected")
case .message(let msg):
print("msg \(msg)")
writeSubject.onNext(msg) // 5-1. 내려온 데이터를 subject로 넘기기
// TODO: 여기서 decoding을 처리한 후 subject로 보내도 좋습니다!
case .data(let data):
print("data \(data)")
case .pong:
print("pong")
default:
print("default")
}
}.disposed(by: bag)
// 6. 서브젝트를 UILabel에서 구독해서 처리
writeSubject.asObservable()
.bind(to: loadLabel.rx.text)
.disposed(by: bag)
}
}
extension RxStarScream {
// 4. 웹 소켓 서버에 write
fileprivate func sendMessage(message: String) {
webSocket.write(string: message) // 4-1. 웹소켓 서버에 request 데이터 전달
writeSubject.onNext("SENT: \(message)") // 4-2. 서브젝트에 request 데이터 전달
print("message sendMessage\n\(message)") // 4-3. 어떤 메시지 보냈는지 확인
}
// 2. 웹 소켓 서버와 연결하는 코드
func connect() {
print("connect function")
let url = "{YOUR WEB SOCKET AVAIABLE SERVER}"
var request = URLRequest(url: URL(string: url)!)
request.addValue("{YOUR SERVER}", forHTTPHeaderField: "Origin") // HTTPUpgrade error 발생 시 넣어주면 됩니다.
request.timeoutInterval = 10
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
webSocket = WebSocket(request: request)
webSocket.connect()
}
func disconnect() {
webSocket.disconnect()
}
}
extension RxStarScream {
private func setupViews() {
[loadBtn, loadLabel].forEach {
view.addSubview($0)
}
}
private func setConstraints() {
loadBtn.snp.makeConstraints {
$0.top.left.right.equalToSuperview()
$0.bottom.equalToSuperview().offset(-100)
}
loadLabel.snp.makeConstraints {
$0.top.equalTo(loadBtn.snp.bottom)
$0.left.right.bottom.equalToSuperview()
}
}
}
위에 숫자를 넣어서 데이터의 흐름이 어떻게 되는지 알 수 있게 해두었으니까, 꼭 확인해보기!
다음 포스팅은 아마 WebSocket을 오리지널 하게 사용하는 방법에 대해서 알아볼 예정이야.