添加 ServerManager,支持多服务器。

This commit is contained in:
Fin 2022-03-25 12:27:44 +08:00
parent 043bab5569
commit 8572970c62
9 changed files with 152 additions and 94 deletions

View File

@ -107,7 +107,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
Client.shared.deviceToken.accept(deviceTokenString)
//
Client.shared.bindDeviceToken()
ServerManager.shared.syncAllServers()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
@ -206,9 +206,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
func applicationWillEnterForeground(_ application: UIApplication) {
if (Client.shared.key?.count ?? 0) <= 0 {
Client.shared.bindDeviceToken()
}
ServerManager.shared.syncAllServers()
// -1
// 0

View File

@ -10,10 +10,14 @@ import DefaultsKit
import UIKit
enum BarkSettingKey: String {
/// key
/// key , 1.2.6 ``使
case key = "me.fin.bark.key"
case servers = "me.fin.bark.servers"
/// 1.2.6 `` server key使
case currentServer = "me.fin.bark.servers.current"
/// 1.2.6 `` server id
case currentServerId = "me.fin.bark.servers.currentServerId"
case selectedViewControllerIndex = "me.fin.bark.selectedViewControllerIndex"
}

View File

@ -38,56 +38,15 @@ class Client: NSObject {
return version
}()
private var _key: String?
var key: String? {
get {
if _key == nil, let aKey = Settings[.key] {
_key = aKey
}
return _key
}
set {
_key = newValue
Settings[.key] = newValue
}
}
enum ClienState {
enum ClienState: Int, Codable {
case ok
case unRegister
case serverError
}
var deviceToken = BehaviorRelay<String?>(value: nil)
var state = BehaviorRelay<ClienState>(value: .ok)
var dispose: Disposable?
func bindDeviceToken() {
if let token = deviceToken.value, token.count > 0 {
dispose?.dispose()
dispose = BarkApi.provider
.request(.register(
key: key,
devicetoken: token))
.filterResponseError()
.map { json -> ClienState in
switch json {
case .success(let json):
if let key = json["data", "key"].rawString() {
Client.shared.key = key
return .ok
}
else {
return .serverError
}
case .failure:
return .serverError
}
}
.bind(to: state)
}
}
func registerForRemoteNotifications() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { (_ granted: Bool, _: Error?) -> Void in

View File

@ -10,20 +10,27 @@ import UIKit
enum BarkApi {
case ping(baseURL: String?)
case register(key: String?, devicetoken: String) //
case register(address: String, key: String?, devicetoken: String) //
}
extension BarkApi: BarkTargetType {
var baseURL: URL {
if case let .ping(urlStr) = self, let url = URL(string: urlStr ?? "") {
return url
switch self {
case let .ping(urlStr):
if let url = URL(string: urlStr ?? "") {
return url
}
case let .register(address, _, _):
if let url = try? address.asURL() {
return url
}
}
return URL(string: ServerManager.shared.currentAddress)!
return try! ServerManager.shared.currentServer.address.asURL()
}
var parameters: [String: Any]? {
switch self {
case let .register(key, devicetoken):
case let .register(_, key, devicetoken):
var params = ["devicetoken": devicetoken]
if let key = key {
params["key"] = key

View File

@ -23,7 +23,7 @@ extension BarkTargetType {
}
var baseURL: URL {
return URL(string: ServerManager.shared.currentAddress)!
return URL(string: ServerManager.shared.currentServer.address)!
}
var method: Moya.Method {
@ -54,21 +54,6 @@ extension BarkTargetType {
return Task.requestParameters(parameters: defaultParameters, encoding: parameterEncoding)
}
static var networkActivityPlugin: PluginType {
return NetworkActivityPlugin { change, _ in
switch change {
case .began:
dispatch_sync_safely_main_queue {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
case .ended:
dispatch_sync_safely_main_queue {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
}
}
/// provider
static var provider: RxSwift.Reactive<MoyaProvider<Self>> {
let key = "\(Self.self)"
@ -82,7 +67,7 @@ extension BarkTargetType {
/// Provider 使
static var weakProvider: RxSwift.Reactive<MoyaProvider<Self>> {
var plugins: [PluginType] = [networkActivityPlugin]
var plugins: [PluginType] = []
#if DEBUG
plugins.append(LogPlugin())
#endif

View File

@ -6,43 +6,95 @@
// Copyright © 2018 Fin. All rights reserved.
//
import RxSwift
import SwiftUI
import UIKit
let defaultServer = "https://api.day.app"
class Server: Codable {
let id: String
let address: String
var key: String
var state: Client.ClienState
init(id: String = UUID().uuidString, address: String, key: String, state: Client.ClienState = .ok) {
self.id = id
self.address = address
self.key = key
self.state = state
}
}
class ServerManager: NSObject {
static let shared = ServerManager()
override private init() {
if let servers: Set<String> = Settings[.servers] {
if let servers: [Server] = Settings[.servers] {
self.servers = servers
}
if servers.count <= 0 {
servers = [Server(id: UUID().uuidString, address: defaultServer, key: "")]
}
self.currentServer = servers[0]
super.init()
//
if let address = Settings[.currentServer] {
self.currentAddress = address
let key = Settings[.key] ?? ""
let server = Server(id: UUID().uuidString, address: address, key: key)
self.servers = []
self.addServer(server: server)
Settings[.currentServerId] = server.id
//
Settings[.currentServer] = nil
Settings[.key] = nil
}
if let currentServerId = Settings[.currentServerId] {
self.setCurrentServer(serverId: currentServerId)
}
}
/// server
var servers: [Server] = []
/// server
private(set) var currentServer: Server
/// server
func setCurrentServer(serverId: String) {
if let server = servers.first(where: { $0.id == serverId }) {
currentServer = server
}
else {
self.currentAddress = self.servers.first ?? defaultServer
currentServer = servers.first!
}
super.init()
Settings[.currentServerId] = serverId
}
var servers: Set<String> = [defaultServer]
var currentAddress: String {
didSet {
Settings[.currentServer] = currentAddress
}
/// server
func addServer(server: Server) {
self.servers.append(server)
saveServers()
}
func addServer(server: String) {
self.servers.insert(server)
Settings[.servers] = self.servers
}
func removeServer(server: String) {
self.servers.remove(server)
/// server server ``, `server`
func removeServer(server: Server) {
self.servers.removeAll { $0.id == server.id }
if self.servers.count <= 0 {
self.servers.insert(defaultServer)
self.servers.append(
Server(id: UUID().uuidString, address: defaultServer, key: "")
)
self.setCurrentServer(serverId: self.servers[0].id)
}
saveServers()
}
/// servers
func saveServers() {
Settings[.servers] = self.servers
}
@ -50,4 +102,55 @@ class ServerManager: NSObject {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var dispose: Disposable?
/// server
func syncAllServers() {
guard let token = Client.shared.deviceToken.value, token.count > 0 else {
return
}
dispose?.dispose()
let apis = servers.map { server in
BarkApi.provider.request(
.register(
address: server.address,
key: server.key,
devicetoken: token))
.filterResponseError()
.map { result -> (Server, String, Client.ClienState) in
switch result {
case .success(let json):
if let key = json["data", "key"].rawString() {
return (server, key, .ok)
}
else {
return (server, "", .serverError)
}
case .failure:
return (server, "", .serverError)
}
}.catch { _ in
Observable.just((server, "", .serverError))
}
}
dispose = Observable
.merge(apis)
.subscribe { result in
// server
result.0.key = result.1
result.0.state = result.2
// server
if result.0.id == self.currentServer.id {
Client.shared.state.accept(result.2)
}
} onError: { _ in
} onCompleted: {
self.saveServers()
}
}
}

View File

@ -102,7 +102,7 @@ class HomeViewModel: ViewModel, ViewModelType {
}()
func transform(input: Input) -> Output {
let title = BehaviorRelay(value: URL(string: ServerManager.shared.currentAddress)?.host ?? "")
let title = BehaviorRelay(value: URL(string: ServerManager.shared.currentServer.address)?.host ?? "")
let sectionModel = SectionModel(
model: "previews",
@ -127,7 +127,7 @@ class HomeViewModel: ViewModel, ViewModelType {
let clienState = input.viewDidAppear
.asObservable().flatMapLatest { _ -> Observable<Result<JSON, ApiError>> in
BarkApi.provider
.request(.ping(baseURL: ServerManager.shared.currentAddress))
.request(.ping(baseURL: ServerManager.shared.currentServer.address))
.filterResponseError()
}
.map { response -> Client.ClienState in

View File

@ -76,8 +76,10 @@ class NewServerViewModel: ViewModel, ViewModelType {
guard let strongSelf = self else { return }
switch response {
case .success:
ServerManager.shared.currentAddress = strongSelf.url
Client.shared.bindDeviceToken()
let server = Server(address: strongSelf.url, key: "")
ServerManager.shared.addServer(server: server)
ServerManager.shared.setCurrentServer(serverId: server.id)
ServerManager.shared.syncAllServers()
strongSelf.pop.accept(strongSelf.url)
showSnackbar.accept(NSLocalizedString("AddedSuccessfully"))

View File

@ -65,14 +65,14 @@ class PreviewCardCellViewModel: ViewModel {
if UIScreen.main.bounds.size.width <= 320 {
fontSize = 11
}
let serverUrl = URL(string: ServerManager.shared.currentAddress)!
let serverUrl = URL(string: ServerManager.shared.currentServer.address)!
let attrStr = NSMutableAttributedString(string: "")
attrStr.append(NSAttributedString(string: serverUrl.absoluteString, attributes: [
NSAttributedString.Key.foregroundColor: BKColor.grey.darken4,
NSAttributedString.Key.font: RobotoFont.regular(with: fontSize)
]))
attrStr.append(NSAttributedString(string: "/\(Client.shared.key ?? "Your Key")", attributes: [
let key = ServerManager.shared.currentServer.key
attrStr.append(NSAttributedString(string: "/\(key.count > 0 ? key : "Your Key")", attributes: [
NSAttributedString.Key.foregroundColor: BKColor.grey.darken3,
NSAttributedString.Key.font: RobotoFont.regular(with: fontSize)
]))