diff --git a/ios/App/App/plugins/AbsDatabase.m b/ios/App/App/plugins/AbsDatabase.m index 6225a74b..5d45a91c 100644 --- a/ios/App/App/plugins/AbsDatabase.m +++ b/ios/App/App/plugins/AbsDatabase.m @@ -10,6 +10,7 @@ CAP_PLUGIN(AbsDatabase, "AbsDatabase", CAP_PLUGIN_METHOD(setCurrentServerConnectionConfig, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(logout, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getDeviceData, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getLocalLibraryItems, CAPPluginReturnPromise); diff --git a/ios/App/App/plugins/AbsDatabase.swift b/ios/App/App/plugins/AbsDatabase.swift index 6c98906f..c6c29c2a 100644 --- a/ios/App/App/plugins/AbsDatabase.swift +++ b/ios/App/App/plugins/AbsDatabase.swift @@ -51,18 +51,18 @@ public class AbsDatabase: CAPPlugin { Store.serverConfig = config call.resolve(convertServerConnectionConfigToJSON(config: config)) } + @objc func logout(_ call: CAPPluginCall) { + Store.serverConfig = nil + call.resolve() + } + @objc func getDeviceData(_ call: CAPPluginCall) { let configs = Database.getServerConnectionConfigs() - let index = Database.getActiveServerConfigIndex() + let index = Database.getLastActiveConfigIndex() call.resolve([ - "serverConnectionConfigs": configs.map { config in - return convertServerConnectionConfigToJSON(config: config) - }, - "lastServerConnectionConfigId": index < 0 ? -1 : configs.first(where: { - (config: ServerConnectionConfig) -> Bool in - return config.index == index - })!.id, + "serverConnectionConfigs": configs.map { config in convertServerConnectionConfigToJSON(config: config) }, + "lastServerConnectionConfigId": configs.first { config in config.index == index }?.id, // Luckily this isn't implemented yet // "currentLocalPlaybackSession": nil, ]) diff --git a/ios/App/Shared/models/ServerConnectionConfig.swift b/ios/App/Shared/models/ServerConnectionConfig.swift index f016f309..c8ace3e1 100644 --- a/ios/App/Shared/models/ServerConnectionConfig.swift +++ b/ios/App/Shared/models/ServerConnectionConfig.swift @@ -17,6 +17,11 @@ class ServerConnectionConfig: Object { @Persisted var username: String @Persisted var token: String } +class ServerConnectionConfigActiveIndex: Object { + // This could overflow, but you really would have to try + @Persisted var index: Int? + +} func convertServerConnectionConfigToJSON(config: ServerConnectionConfig) -> Dictionary { return Database.realmQueue.sync { diff --git a/ios/App/Shared/player/AudioPlayer.swift b/ios/App/Shared/player/AudioPlayer.swift index 26640333..bb155e21 100644 --- a/ios/App/Shared/player/AudioPlayer.swift +++ b/ios/App/Shared/player/AudioPlayer.swift @@ -164,11 +164,11 @@ class AudioPlayer: NSObject { // MARK: - Private private func createAsset() -> AVAsset { let headers: [String: String] = [ - "Authorization": "Bearer \(Store.serverConfig.token)" + "Authorization": "Bearer \(Store.serverConfig!.token)" ] debugPrint(activeAudioTrack) - return AVURLAsset(url: URL(string: "\(Store.serverConfig.address)\(activeAudioTrack.contentUrl)")!, options: ["AVURLAssetHTTPHeaderFieldsKey": headers]) + return AVURLAsset(url: URL(string: "\(Store.serverConfig!.address)\(activeAudioTrack.contentUrl)")!, options: ["AVURLAssetHTTPHeaderFieldsKey": headers]) } private func initAudioSession() { do { diff --git a/ios/App/Shared/util/ApiClient.swift b/ios/App/Shared/util/ApiClient.swift index b546d244..e9e01aea 100644 --- a/ios/App/Shared/util/ApiClient.swift +++ b/ios/App/Shared/util/ApiClient.swift @@ -24,10 +24,10 @@ class ApiClient { public static func postResource(endpoint: String, parameters: [String: String], decodable: T.Type = T.self, callback: ((_ param: T) -> Void)?) { let headers: HTTPHeaders = [ - "Authorization": "Bearer \(Store.serverConfig.token)" + "Authorization": "Bearer \(Store.serverConfig!.token)" ] - AF.request("\(Store.serverConfig.address)/\(endpoint)", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default, headers: headers).responseDecodable(of: decodable) { response in + AF.request("\(Store.serverConfig!.address)/\(endpoint)", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default, headers: headers).responseDecodable(of: decodable) { response in switch response.result { case .success(let obj): callback?(obj) @@ -50,8 +50,8 @@ class ApiClient { ], decodable: PlaybackSession.self) { obj in var session = obj - session.serverConnectionConfigId = Store.serverConfig.id - session.serverAddress = Store.serverConfig.address + session.serverConnectionConfigId = Store.serverConfig!.id + session.serverAddress = Store.serverConfig!.address callback(session) } diff --git a/ios/App/Shared/util/Database.swift b/ios/App/Shared/util/Database.swift index f6cd9d98..902aeb8e 100644 --- a/ios/App/Shared/util/Database.swift +++ b/ios/App/Shared/util/Database.swift @@ -9,23 +9,12 @@ import Foundation import RealmSwift class Database { - public static let realmQueue = DispatchQueue(label: "realm-queue") - // All DB releated actions must be executed on "realm-queue" + public static let realmQueue = DispatchQueue(label: "realm-queue") private static var instance: Realm = { - // TODO: handle thread errors try! Realm(queue: realmQueue) }() - public static func getActiveServerConfigIndex() -> Int { - return realmQueue.sync { - guard let config = instance.objects(ServerConnectionConfig.self).first else { - return -1 - } - return config.index - } - } - public static func setServerConnectionConfig(config: ServerConnectionConfig) { var refrence: ThreadSafeReference? if config.realm != nil { @@ -35,6 +24,16 @@ class Database { realmQueue.sync { let existing: ServerConnectionConfig? = instance.object(ofType: ServerConnectionConfig.self, forPrimaryKey: config.id) + if config.index == 0 { + let lastConfig: ServerConnectionConfig? = instance.objects(ServerConnectionConfig.self).last + + if lastConfig != nil { + config.index = lastConfig!.index + 1 + } else { + config.index = 1 + } + } + do { try instance.write { if existing != nil { @@ -54,6 +53,8 @@ class Database { NSLog("failed to save server config") debugPrint(exception) } + + setLastActiveConfigIndex(index: config.index) } } public static func getServerConnectionConfigs() -> [ServerConnectionConfig] { @@ -78,4 +79,30 @@ class Database { return [] } } + + public static func setLastActiveConfigIndexToNil() { + realmQueue.sync { + setLastActiveConfigIndex(index: nil) + } + } + public static func setLastActiveConfigIndex(index: Int?) { + let existing = instance.objects(ServerConnectionConfigActiveIndex.self) + let obj = ServerConnectionConfigActiveIndex() + obj.index = index + + do { + try instance.write { + instance.delete(existing) + instance.add(obj) + } + } catch(let exception) { + NSLog("failed to save server config active index") + debugPrint(exception) + } + } + public static func getLastActiveConfigIndex() -> Int? { + return realmQueue.sync { + return instance.objects(ServerConnectionConfigActiveIndex.self).first?.index ?? nil + } + } } diff --git a/ios/App/Shared/util/NowPlayingInfo.swift b/ios/App/Shared/util/NowPlayingInfo.swift index 812848f2..ec711019 100644 --- a/ios/App/Shared/util/NowPlayingInfo.swift +++ b/ios/App/Shared/util/NowPlayingInfo.swift @@ -37,7 +37,7 @@ class NowPlayingInfo { } */ - guard let url = URL(string: "\(Store.serverConfig.address)/api/items/\(metadata.itemId)/cover?token=\(Store.serverConfig.token)") else { + guard let url = URL(string: "\(Store.serverConfig!.address)/api/items/\(metadata.itemId)/cover?token=\(Store.serverConfig!.token)") else { return } diff --git a/ios/App/Shared/util/Store.swift b/ios/App/Shared/util/Store.swift index 367a9362..400ee06d 100644 --- a/ios/App/Shared/util/Store.swift +++ b/ios/App/Shared/util/Store.swift @@ -10,20 +10,17 @@ import RealmSwift class Store { @ThreadSafe private static var _serverConfig: ServerConnectionConfig? - public static var serverConfig: ServerConnectionConfig { + public static var serverConfig: ServerConnectionConfig? { get { - if _serverConfig == nil { - let index = Database.getActiveServerConfigIndex() - // TODO: change this when multiple configs are possible - _serverConfig = Database.getServerConnectionConfigs().first { config in - return config.index == index - } - } - - return _serverConfig ?? ServerConnectionConfig() + return _serverConfig } set(updated) { - Database.setServerConnectionConfig(config: updated) + if updated != nil { + Database.setServerConnectionConfig(config: updated!) + } else { + Database.setLastActiveConfigIndexToNil() + } + _serverConfig = nil } }