How can i make a single class manager of starscream web sockets in swift. Kindly help me out how can i do that to get request and response just by managing singleton class manager.
Because i want to use sockets over the app in many views and there child views, it's not good practice i can initiate delegate method on every class and get request and response.
One more question how can i authenticate using websockets format is:
{'UsernameAuth':'Username', 'PasswordAuth':'Password'}
Kindly help me out.
Thanks
Singletones in Swift are quite trivial. Create a separate Swift file: WSHub.swift
Hub is supposed to deliver messages to observers.
import Srascream
@objc protocol WSHubObserver: class {
optional func wsHub(_ hub: WSHub, receivedText: String)
optional func wsHub(_ hub: WSHub, receivedJsonDic: [String: Any])
optional func wsHub(_ hub: WSHub, receivedJsonArray: [Any])
}
class WSHub: NSObject {
static let shared = WSHub()
private(set) var webSocket: WebSocket
// Note these observers are referenced and instances will not die unless removed from observers or you can wrap them into WeakRef struct
private var observers: [WSHubObserver] = []
private init() {
self.webSocket = WebSocket(... some URL or URLRequest here...)
super.init()
self.websocket.onText = { [weak self] (text) in
self?.handleText(text)
}
}
public func addObserver(_ observer: WSHubObserver) {
self.observers.append(observer)
}
public func addObserver(_ observer: WSHubObserver) {
if let index = self.objservers.index(observer) {
self.observers.remove(at: index)
}
}
private func handleText(_ text: String) {
self.observers.forEach { observer in
observer.wsHub?(self, receivedText: text)
}
if let data = text.data(using: .utf8),
let object = try? JSONSerialization.jsonObject(with: data, options: []) {
if let dic = object as? [String : Any] {
observer.wsHub?(self, receivedJsonDic: dic)
} else if let arr = object as? [Any] {
observer.wsHub?(self, receivedJsonArray: arr)
}
}
}
}
Then you can use lazily-initialized
singleton at any place in your code WSHub.shared.webSocket.send(...)
Authorization part depends on server. It may be separate URLRequest
to some https://
url with POST
of json data, then you may get response with header Set-Cookie
. And when you are going to connect to websocket, you may create URLRequest
and do request.set(someCookieString, for: "Cookie")
and then server may let you into ws pipe.
I doubt you should sent login/pass every tme you connect as it is bad fashion to store user credentials inside of app, so you should be based on session.
And then your handler:
class SomeWsHubSmallClass: NSObject, WSHubObserver {
func wsHub(_ hub: WSHub, receivedText: String) {
}
func wsHub(_ hub: WSHub, receivedJsonDic: [String: Any]) {
}
func wsHub(_ hub: WSHub, receivedJsonArray: [Any]) {
}
}
let object = SomeWsHubSmallClass()
WSHub.shared.addObserver(object)