Mac OSX Launcher: Moving utils classes to common directory between sub-projects + Swift 4.2 update.

This commit is contained in:
meeh
2019-05-02 22:41:25 +00:00
parent 2af1f68d84
commit 811d1ccf9d
11 changed files with 58 additions and 253 deletions

View File

@@ -25,14 +25,26 @@ class PreferenceRow {
}
class Preferences : NSObject {
enum ShowAsMode {
case bothIcon
case menubarIcon
case dockIcon
}
private var prefObject: Dictionary<String,Any> = Dictionary<String,Any>()
private var prefDict = Dictionary<String,PreferenceRow>()
private var prefDefaultDict: Dictionary<String,Any> = Dictionary<String,Any>()
var notifyOnStatusChange: Bool {
get { return UserDefaults.standard.bool(forKey: "notifyOnStatusChange") }
set { UserDefaults.standard.set(newValue, forKey: "notifyOnStatusChange") }
}
var count: Int = 0
// Interface with a string setting in background
var showAsIconMode: PreferencesViewController.ShowAsMode {
var showAsIconMode: ShowAsMode {
get {
var mode = self["I2Pref_showAsIconMode"]
if (mode == nil) {
@@ -40,13 +52,13 @@ class Preferences : NSObject {
}
switch (mode as! String) {
case "bothIcon":
return PreferencesViewController.ShowAsMode.bothIcon
return ShowAsMode.bothIcon
case "dockIcon":
return PreferencesViewController.ShowAsMode.dockIcon
return ShowAsMode.dockIcon
case "menubarIcon":
return PreferencesViewController.ShowAsMode.menubarIcon
return ShowAsMode.menubarIcon
default:
return PreferencesViewController.ShowAsMode.bothIcon
return ShowAsMode.bothIcon
}
}
set(newVal) {
@@ -83,7 +95,7 @@ class Preferences : NSObject {
}
func syncPref() {
UserDefaults.standard.setPersistentDomain(self.prefObject, forName: APPDOMAIN)
UserDefaults.standard.setPersistentDomain(self.prefObject, forName: Identifiers.applicationDomainId)
UserDefaults.standard.synchronize()
}
@@ -138,7 +150,7 @@ class Preferences : NSObject {
}
preferences.count = preferences.prefDict.keys.count
UserDefaults.standard.register(defaults: defaults)
UserDefaults.standard.setPersistentDomain(preferences.prefObject, forName: APPDOMAIN)
UserDefaults.standard.setPersistentDomain(preferences.prefObject, forName: Identifiers.applicationDomainId)
UserDefaults.standard.synchronize()
print("User Preferences loaded - Got \(preferences.count) items.")
@@ -166,7 +178,7 @@ class Preferences : NSObject {
private override init() {
super.init()
let fromDisk = UserDefaults.standard.persistentDomain(forName: APPDOMAIN) ?? Dictionary<String,Any>()
let fromDisk = UserDefaults.standard.persistentDomain(forName: Identifiers.applicationDomainId) ?? Dictionary<String,Any>()
for (pKey, pVal) in fromDisk {
if (pKey.starts(with: "I2P")) {
print("Preference -> \(pKey)")

View File

@@ -23,7 +23,7 @@ class ReflectionFunctions {
func methodName(m: Method) -> String? {
let sel = method_getName(m)
let nameCString = sel_getName(sel)
return String(cString: nameCString!)
return String(cString: nameCString)
}
/// Print the names for each method in a class
@@ -32,7 +32,7 @@ class ReflectionFunctions {
let methodList = class_copyMethodList(cls, &methodCount)
if methodList != nil && methodCount > 0 {
enumerateCArray(array: methodList!, count: methodCount) { i, m in
let name = methodName(m: m!) ?? "unknown"
let name = methodName(m: m) ?? "unknown"
print("#\(i): \(name)")
}

View File

@@ -8,6 +8,7 @@
import Foundation
class Startup : NSObject {
let loginItemsList : LSSharedFileList = LSSharedFileListCreate(nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue();
@@ -21,7 +22,7 @@ class Startup : NSObject {
return true;
}
var path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
let path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
print("Path adding to Login Item list is: ", path);
// add new Login Item at the end of Login Items list
@@ -55,7 +56,7 @@ class Startup : NSObject {
func getLoginItem(_ path : CFURL) -> LSSharedFileListItem! {
var path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
let path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
// Copy all login items in the list
@@ -69,7 +70,7 @@ class Startup : NSObject {
for var i in (0..<loginItems.count) // CFArrayGetCount(loginItems)
{
var nextLoginItem : LSSharedFileListItem = loginItems.object(at: i) as! LSSharedFileListItem; // CFArrayGetValueAtIndex(loginItems, i).;
let nextLoginItem : LSSharedFileListItem = loginItems.object(at: i) as! LSSharedFileListItem; // CFArrayGetValueAtIndex(loginItems, i).;
if(LSSharedFileListItemResolve(nextLoginItem, 0, &nextItemUrl, nil) == noErr) {

View File

@@ -72,3 +72,35 @@ extension String {
}
}
/*
* This is functions for comparing version numbers.
* Example usage:
* "3.0.0" >= "3.0.0.1" // false
* "3.0.0" > "3.0.0.1" // false
* "3.0.0" <= "3.0.0.1" // true
* "3.0.0.1" >= "3.0.0.1" // true
*/
extension String {
static func ==(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedSame
}
static func <(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedAscending
}
static func <=(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedAscending || lhs.compare(rhs, options: .numeric) == .orderedSame
}
static func >(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedDescending
}
static func >=(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedDescending || lhs.compare(rhs, options: .numeric) == .orderedSame
}
}

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="oLh-xo-y8T">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Window Controller-->
<scene sceneID="g0w-9k-Acs">
<objects>
<windowController id="oLh-xo-y8T" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="5Sr-7Y-gfA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="294" y="362" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<connections>
<outlet property="delegate" destination="oLh-xo-y8T" id="Fxx-ke-F0n"/>
</connections>
</window>
<connections>
<segue destination="nXM-BR-Lxj" kind="relationship" relationship="window.shadowedContentViewController" id="3cB-Gf-aj2"/>
</connections>
</windowController>
<customObject id="K5y-Qa-lNJ" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="50" y="118"/>
</scene>
<!--Console View Controller-->
<scene sceneID="MSW-MZ-pqs">
<objects>
<viewController id="nXM-BR-Lxj" customClass="ConsoleViewController" customModule="I2PLauncher" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="Omy-Aq-Pw7">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</viewController>
<customObject id="LZW-ak-seY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="757" y="93"/>
</scene>
</scenes>
</document>

View File

@@ -1,88 +0,0 @@
//
// EmbeddedConsoleView.swift
// I2PLauncher
//
// Created by Mikal Villa on 08/12/2018.
// Copyright © 2018 The I2P Project. All rights reserved.
//
import AppKit
import WebKit
/*
protocol EConsoleViewWrapper {}
class WebViewSource {
class func webView() -> EConsoleViewWrapper {
if #available(OSX 10.12, *) {
//
return EmbeddedConsoleView(coder: NSCoder())!
} else {
// Sorry
return EmbeddedConsoleViewDummy()
}
}
}
extension EConsoleViewWrapper {
static func instantiate(frame frameRect: NSRect) -> EConsoleViewWrapper {
return WebViewSource.webView()
}
}
*/
class ConsoleWindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
/* let v: NSView = WebViewSource.webView() as! NSView
v.wantsLayer = true
self.window?.contentView?.addSubview(v)*/
}
}
class ConsoleViewController: NSViewController {
var webView: WKWebView!
let consoleWebUrl = URL(string: "http://127.0.0.1:7657")
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
//webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.load(URLRequest(url: consoleWebUrl!))
}
}
/*
@available(OSX 10.12, *)
class EmbeddedConsoleView: WKWebView, EConsoleViewWrapper {
let consoleWebUrl = URL(string: "http://127.0.0.1:7657")
func setupWebViewForConsole(_ f: NSRect = NSRect(x: 0, y: 0, width: 800, height: 400)) {
self.allowsBackForwardNavigationGestures = true
self.configuration.preferences.javaScriptEnabled = true
self.configuration.preferences.plugInsEnabled = false
self.load(URLRequest(url: consoleWebUrl!))
}
override func viewWillDraw() {
super.viewWillDraw()
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
self.setupWebViewForConsole()
}
}
class EmbeddedConsoleViewDummy: NSView, EConsoleViewWrapper {}
*/

View File

@@ -1,108 +0,0 @@
//
// FirefoxManager.swift
// I2PLauncher
//
// Created by Mikal Villa on 08/12/2018.
// Copyright © 2018 The I2P Project. All rights reserved.
//
import Foundation
class FirefoxManager {
var firefoxAppPath = ""
private var isFirefoxFound = false
private var isFirefoxProfileExtracted = false
fileprivate func directoryExistsAtPath(_ path: String) -> Bool {
var isDirectory = ObjCBool(true)
let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory)
return exists && isDirectory.boolValue
}
func IsFirefoxFound() -> Bool {
return self.isFirefoxFound
}
func IsProfileExtracted() -> Bool {
return self.isFirefoxProfileExtracted
}
// Since we execute in the "unix/POSIX way", we need the full path of the binary.
func bundleExecutableSuffixPath() -> String {
return "/Contents/MacOS/firefox"
}
func executeFirefox() -> Bool {
let fullExecPath = "\(self.firefoxAppPath)\(self.bundleExecutableSuffixPath())"
let firefoxProcess = Subprocess(executablePath: fullExecPath, arguments: [ "-profile", Preferences.shared()["I2Pref_firefoxProfilePath"] as! String, "http://127.0.0.1:7657/home" ])
DispatchQueue.global(qos: .background).async {
let proc = firefoxProcess.execute()
}
return true
}
/**
*
* First, try find I2P Browser, if it fails, then try Firefox or Firefox Developer.
*
* Instead of using hardcoded paths, or file search we use OS X's internal "registry" API
* and detects I2P Browser or Firefox by bundle name. (or id, but name is more readable)
*
*/
func tryAutoDetect() -> Bool {
var browserPath = NSWorkspace.shared().fullPath(forApplication: "I2P Browser")
if (browserPath == nil)
{
browserPath = NSWorkspace.shared().fullPath(forApplication: "Firefox")
if (browserPath == nil)
{
browserPath = NSWorkspace.shared().fullPath(forApplication: "Firefox Developer")
}
}
self.isFirefoxProfileExtracted = directoryExistsAtPath(Preferences.shared()["I2Pref_firefoxProfilePath"] as! String)
// If browserPath is still nil, then nothing above was found and we can return early.
if (browserPath == nil)
{
return false
}
let result = directoryExistsAtPath(browserPath!)
self.isFirefoxFound = result
if (result) {
self.firefoxAppPath = browserPath!
return true
}
return false
}
private static var sharedFirefoxManager: FirefoxManager = {
let firefoxMgr = FirefoxManager()
return firefoxMgr
}()
class func shared() -> FirefoxManager {
return sharedFirefoxManager
}
}
extension FirefoxManager {
func unzipProfile() -> Bool {
let resourceUrl = Bundle.main.url(forResource: "profile", withExtension: "tgz")
let profileTgz = resourceUrl!.path
let unzipProc = Subprocess(executablePath: "/usr/bin/tar", arguments: ["-xf",profileTgz,"-C",NSString(format: "%@/Library/Application Support/i2p", NSHomeDirectory()) as String])
DispatchQueue.global(qos: .background).async {
let proc = unzipProc.execute(captureOutput: true)
print("Firefox Profile Extraction Errors: \(proc?.errors)")
print("Firefox Profile Extraction Output: \(proc?.output)")
}
return false
}
}