Files

272 lines
7.1 KiB
Swift

//
// UserSettings.swift
// Privado
//
// Created by Jura on 11/14/19.
// Copyright © 2019 Omicronmedia. All rights reserved.
//
import Foundation
import CoreData
final class UserSettings {
// MARK: - Properties
static var shared = UserSettings()
private var settings: Settings?
let vpnTypeEmitter = Emitter<VPNType?>()
let vpnConfigurationEmitter = Emitter<Void>()
let settingsEmitter = Emitter<Settings>()
let killSwitchEmitter = Emitter<Bool>()
var alreadyLaunched: Bool {
get {
UserDefaults.standard.bool(forKey: "alreadyLaunched")
}
set {
UserDefaults.standard.set(newValue, forKey: "alreadyLaunched")
}
}
var tutorialAlreadyShown: Bool {
get {
UserDefaults.standard.bool(forKey: "tutorialAlreadyShown")
}
set {
UserDefaults.standard.set(newValue, forKey: "tutorialAlreadyShown")
}
}
var newlyCreatedEmail: String? {
get {
UserDefaults.standard.string(forKey: "newlyCreatedEmail")
}
set {
UserDefaults.standard.set(newValue, forKey: "newlyCreatedEmail")
}
}
var lastUsedServer: String {
get {
self.settings?.lastUsedServer ?? ""
}
set {
guard let settings = self.settings else { return }
settings.lastUsedServer = newValue
self.save(settings: settings)
}
}
var autostartEnabled: Bool {
get {
self.settings?.autostartEnabled ?? false
}
set {
guard let settings = self.settings else { return }
settings.autostartEnabled = newValue
self.save(settings: settings)
self.settingsEmitter.invoke(settings)
}
}
var preferredServer: PreferredServerType {
get {
return PreferredServerType(rawValue: self.settings?.preferredServer ?? 0) ?? .none
}
set {
guard newValue != self.preferredServer else { return }
guard let settings = self.settings else { return }
settings.preferredServer = newValue.rawValue
self.save(settings: settings)
}
}
var killSwitchEnabled: Bool {
get {
self.settings?.killSwitchEnabled ?? false
}
set {
guard let settings = self.settings else { return }
let changed = settings.killSwitchEnabled != newValue
settings.killSwitchEnabled = newValue
self.save(settings: settings)
if changed { self.killSwitchEmitter.invoke(newValue) }
self.settingsEmitter.invoke(settings)
}
}
var vpnType: VPNType? {
get {
guard let value = self.settings?.vpnType
, let type = VPNType(rawValue: value) else {
return nil
}
return type
}
set {
guard newValue != self.vpnType else { return }
guard let settings = self.settings else { return }
if let value = newValue {
settings.vpnType = value.rawValue
} else {
settings.vpnType = nil
}
self.save(settings: settings)
guard let value = newValue else { return }
self.vpnTypeEmitter.invoke(value)
}
}
var scramble: Bool {
get {
self.settings?.scramble == 1
}
set {
guard newValue != self.scramble else { return }
guard let settings = self.settings else { return }
settings.scramble = newValue ? 1 : 0
self.save(settings: settings)
self.vpnConfigurationEmitter.invoke(())
}
}
var proto: String {
get {
self.settings?.proto ?? "TCP"
}
set {
guard newValue != self.proto else { return }
guard let settings = self.settings else { return }
settings.proto = newValue
self.save(settings: settings)
self.vpnConfigurationEmitter.invoke(())
}
}
var port: Int16 {
get {
self.settings?.port ?? 1194
}
set {
guard newValue != self.port else { return }
guard let settings = self.settings else { return }
settings.port = newValue
self.save(settings: settings)
self.vpnConfigurationEmitter.invoke(())
}
}
var isCrashReportsEnabled: Bool {
get {
self.settings?.isCrashReportsEnabled ?? true
}
set {
guard newValue != self.isCrashReportsEnabled else { return }
guard let settings = self.settings else { return }
settings.isCrashReportsEnabled = newValue
self.save(settings: settings)
CometLogger.shared.changeLoggersState(isActive: newValue)
}
}
var lastConnectionState: String {
get {
self.settings?.lastConnectionState ?? ""
}
set {
guard newValue != self.lastConnectionState else { return }
guard let settings = self.settings else { return }
settings.lastConnectionState = newValue
self.save(settings: settings)
}
}
// MARK: - Initializers
private init() {
self.restore()
}
deinit {
self.settings = nil
}
func clear() {
guard let coordinator = DatabaseAnswer.commonDB else { return }
let request: NSFetchRequest<Settings> = Settings.fetchRequest()
let context = coordinator.createContext()
let settings: [Settings] = context.fetch(request)
settings.forEach {
context.delete($0)
}
context.save()
coordinator.save()
self.settings = nil
self.restore()
}
// MARK: - Private
private func save(settings: Settings) {
guard let coordinator = DatabaseAnswer.commonDB else { return }
coordinator.mainContext.save()
coordinator.save()
}
private func restore() {
guard let coordinator = DatabaseAnswer.commonDB else { return }
if let settings: Settings = coordinator.mainContext.fetch(Settings.fetchRequest()).first {
self.settings = settings
} else {
let settings: Settings = coordinator.mainContext.create()
settings.id = UUID().uuidString
coordinator.mainContext.save()
coordinator.save()
self.settings = settings
}
}
}