Carthage copy-frameworks + Filter changed extension reload
This commit is contained in:
@@ -12,10 +12,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
if UserDefaults.standard.bool(forKey: "kill_db") {
|
||||
UserDefaults.standard.set(false, forKey: "kill_db")
|
||||
SQLiteDatabase.destroyDatabase(path: DB_PATH)
|
||||
SQLiteDatabase.destroyDatabase()
|
||||
}
|
||||
do {
|
||||
let db = try SQLiteDatabase.open(path: DB_PATH)
|
||||
let db = try SQLiteDatabase.open()
|
||||
try db.createTable(table: DNSQuery.self)
|
||||
try db.createTable(table: DNSFilter.self)
|
||||
} catch {}
|
||||
@@ -27,6 +27,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
self.postVPNState()
|
||||
}
|
||||
NSNotification.Name.NEVPNStatusDidChange.observe(call: #selector(vpnStatusChanged(_:)), on: self)
|
||||
NotifyFilterChanged.observe(call: #selector(filterDidChange), on: self)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -34,6 +35,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
postRawVPNState((notification.object as? NETunnelProviderSession)?.status ?? .invalid)
|
||||
}
|
||||
|
||||
@objc private func filterDidChange() {
|
||||
// Notify VPN extension about changes
|
||||
if let session = self.managerVPN?.connection as? NETunnelProviderSession,
|
||||
session.status == .connected {
|
||||
try? session.sendProviderMessage("filter-update".data(using: .ascii)!, responseHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func setProxyEnabled(_ newState: Bool) {
|
||||
guard let mgr = self.managerVPN else {
|
||||
self.createNewVPN { manager in
|
||||
@@ -42,7 +51,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
}
|
||||
return
|
||||
}
|
||||
let state = mgr.isEnabled && (mgr.connection.status == NEVPNStatus.connected)
|
||||
let state = mgr.isEnabled && (mgr.connection.status == .connected)
|
||||
if state != newState {
|
||||
self.updateVPN({ mgr.isEnabled = true }) {
|
||||
newState ? try? mgr.connection.startVPNTunnel() : mgr.connection.stopVPNTunnel()
|
||||
|
||||
@@ -65,7 +65,7 @@ class DBWrapper {
|
||||
let list = AppDB?.loadFilters() ?? [:]
|
||||
Q.async(flags: .barrier) {
|
||||
self.dataF = list
|
||||
NotifyFilterChanged.postOnMainThread()
|
||||
NotifyFilterChanged.postAsyncMain()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class DBWrapper {
|
||||
self.latestModification = max(parent.lastModified, self.latestModification)
|
||||
}
|
||||
}
|
||||
NotifyLogHistoryReset.postOnMainThread()
|
||||
NotifyLogHistoryReset.postAsyncMain()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ class DBWrapper {
|
||||
self.dataB_delegate(self.dataA[i].domain)?.replaceRow(self.dataB[i][u], at: u)
|
||||
}
|
||||
}
|
||||
NotifyFilterChanged.postOnMainThread()
|
||||
NotifyFilterChanged.postAsyncMain()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import Foundation
|
||||
import SQLite3
|
||||
|
||||
let exportPath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||
let basePath = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.de.uni-bamberg.psi.AppCheck")
|
||||
let DB_PATH = basePath!.appendingPathComponent("dns-logs.sqlite").relativePath
|
||||
|
||||
typealias Timestamp = Int64
|
||||
struct GroupedDomain {
|
||||
let domain: String, total: Int32, blocked: Int32, lastModified: Timestamp
|
||||
@@ -29,7 +25,7 @@ enum SQLiteError: Error {
|
||||
|
||||
// MARK: - SQLiteDatabase
|
||||
|
||||
var AppDB: SQLiteDatabase? { get { try? SQLiteDatabase.open(path: DB_PATH) } }
|
||||
var AppDB: SQLiteDatabase? { get { try? SQLiteDatabase.open() } }
|
||||
|
||||
class SQLiteDatabase {
|
||||
private let dbPointer: OpaquePointer?
|
||||
@@ -49,10 +45,9 @@ class SQLiteDatabase {
|
||||
|
||||
deinit {
|
||||
sqlite3_close(dbPointer)
|
||||
// SQLiteDatabase.destroyDatabase(path: DB_PATH)
|
||||
}
|
||||
|
||||
static func destroyDatabase(path: String) {
|
||||
static func destroyDatabase(path: String = URL.internalDB().relativePath) {
|
||||
if FileManager.default.fileExists(atPath: path) {
|
||||
do { try FileManager.default.removeItem(atPath: path) }
|
||||
catch { print("Could not destroy database file: \(path)") }
|
||||
@@ -62,13 +57,13 @@ class SQLiteDatabase {
|
||||
// static func export() throws -> URL {
|
||||
// let fmt = DateFormatter()
|
||||
// fmt.dateFormat = "yyyy-MM-dd"
|
||||
// let dest = exportPath.appendingPathComponent("\(fmt.string(from: Date()))-dns-log.sqlite")
|
||||
// let dest = FileManager.default.exportDir().appendingPathComponent("\(fmt.string(from: Date()))-dns-log.sqlite")
|
||||
// try? FileManager.default.removeItem(at: dest)
|
||||
// try FileManager.default.copyItem(atPath: DB_PATH, toPath: dest.relativePath)
|
||||
// try FileManager.default.copyItem(at: FileManager.default.internalDB(), to: dest)
|
||||
// return dest
|
||||
// }
|
||||
|
||||
static func open(path: String) throws -> SQLiteDatabase {
|
||||
static func open(path: String = URL.internalDB().relativePath) throws -> SQLiteDatabase {
|
||||
var db: OpaquePointer?
|
||||
//sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_SHAREDCACHE, nil)
|
||||
if sqlite3_open(path, &db) == SQLITE_OK {
|
||||
|
||||
23
main/Extensions/FileManager.swift
Normal file
23
main/Extensions/FileManager.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
import Foundation
|
||||
|
||||
fileprivate extension FileManager {
|
||||
func exportDir() -> URL {
|
||||
try! url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||
}
|
||||
func appGroupDir() -> URL {
|
||||
containerURL(forSecurityApplicationGroupIdentifier: "group.de.uni-bamberg.psi.AppCheck")!
|
||||
}
|
||||
func internalDB() -> URL {
|
||||
appGroupDir().appendingPathComponent("dns-logs.sqlite")
|
||||
}
|
||||
func appGroupIPC() -> URL {
|
||||
appGroupDir().appendingPathComponent("data-exchange.dat")
|
||||
}
|
||||
}
|
||||
|
||||
extension URL {
|
||||
static func exportDir() -> URL { FileManager.default.exportDir() }
|
||||
static func appGroupDir() -> URL { FileManager.default.appGroupDir() }
|
||||
static func internalDB() -> URL { FileManager.default.internalDB() }
|
||||
static func appGroupIPC() -> URL { FileManager.default.appGroupIPC() }
|
||||
}
|
||||
@@ -9,7 +9,7 @@ extension NSNotification.Name {
|
||||
func post(_ obj: Any? = nil) {
|
||||
NotificationCenter.default.post(name: self, object: obj)
|
||||
}
|
||||
func postOnMainThread(_ obj: Any? = nil) {
|
||||
func postAsyncMain(_ obj: Any? = nil) {
|
||||
DispatchQueue.main.async { NotificationCenter.default.post(name: self, object: obj) }
|
||||
}
|
||||
/// You are responsible for removing the returned object in a `deinit` block.
|
||||
|
||||
@@ -17,9 +17,13 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>7</string>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<false/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
@@ -41,9 +45,5 @@
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<false/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -31,10 +31,10 @@ class TVCSettings: UITableViewController {
|
||||
// TODO: export partly?
|
||||
// TODO: show header-banner of success
|
||||
// Share Sheet
|
||||
let sheet = UIActivityViewController(activityItems: [URL(fileURLWithPath: DB_PATH)], applicationActivities: nil)
|
||||
let sheet = UIActivityViewController(activityItems: [URL.internalDB()], applicationActivities: nil)
|
||||
self.present(sheet, animated: true)
|
||||
// Save to Files app
|
||||
// self.present(UIDocumentPickerViewController(url: URL(fileURLWithPath: DB_PATH), in: .exportToService), animated: true)
|
||||
// self.present(UIDocumentPickerViewController(url: FileManager.default.internalDB(), in: .exportToService), animated: true)
|
||||
// Shows Alert and exports to Documents directory
|
||||
// AskAlert(title: "Export results?", text: """
|
||||
// This action will copy the internal database to the app's local Documents directory. You can use the Files app to access the database file.
|
||||
|
||||
@@ -45,7 +45,9 @@ protocol EditActionsIgnoreBlockDelete : EditableRows {
|
||||
extension EditActionsIgnoreBlockDelete where Self: UITableViewController {
|
||||
func editableRowActions(_ index: IndexPath) -> [(RowAction, String)] {
|
||||
let x = dataSource[index.row]
|
||||
QLog.m(x.domain)
|
||||
if x.domain.starts(with: "#") {
|
||||
return [(.delete, "Delete")]
|
||||
}
|
||||
let b = x.options?.contains(.blocked) ?? false
|
||||
let i = x.options?.contains(.ignored) ?? false
|
||||
return [(.delete, "Delete"), (.block, b ? "Unblock" : "Block"), (.ignore, i ? "Unignore" : "Ignore")]
|
||||
|
||||
Reference in New Issue
Block a user