Как сделать синглтон-менеджер класса Starscream в Web-сокете - PullRequest
0 голосов
/ 04 июля 2018

Как я могу сделать одного менеджера класса из starscream веб-сокетов в Swift. Пожалуйста, помогите мне, как я могу сделать это, чтобы получить запрос и ответ, просто управляя синглтон-менеджером класса.

Поскольку я хочу использовать сокеты поверх приложения во многих представлениях и дочерних представлениях, не рекомендуется запускать метод делегата для каждого класса и получать запросы и ответы.

Еще один вопрос, как мне пройти аутентификацию в формате websockets:

{'UsernameAuth':'Username', 'PasswordAuth':'Password'}

Пожалуйста, помогите мне.

Спасибо

1 Ответ

0 голосов
/ 04 июля 2018

Синглтоны в Swift довольно тривиальны. Создайте отдельный файл Swift: WSHub.swift

Хаб должен доставлять сообщения наблюдателям.

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)
            }
        }
    }
}

Тогда вы можете использовать lazily-initialized синглтон в любом месте вашего кода WSHub.shared.webSocket.send(...)

Часть авторизации зависит от сервера. Это может быть отдельный URLRequest для некоторого https:// url с POST данными json, тогда вы можете получить ответ с заголовком Set-Cookie. И когда вы собираетесь подключиться к веб-сокету, вы можете создать URLRequest и выполнить request.set(someCookieString, for: "Cookie"), а затем сервер может пустить вас в канал ws.

Я сомневаюсь, что вам следует отправлять логин / пароль каждый раз, когда вы подключаетесь, так как хранить учетные данные пользователя внутри приложения - это нехорошо, поэтому вы должны основываться на сеансе.

А потом ваш обработчик:

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)
...