Conversion to Swift 4.

This commit is contained in:
Qiu Yuzhou
2017-10-20 18:39:25 +08:00
parent 3faad7b07d
commit d56b108eb8
9 changed files with 117 additions and 112 deletions

View File

@ -532,11 +532,11 @@
TargetAttributes = { TargetAttributes = {
9B0BFFE41D0460A70040E62B = { 9B0BFFE41D0460A70040E62B = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800; LastSwiftMigration = 0900;
}; };
9B0BFFF31D0460A70040E62B = { 9B0BFFF31D0460A70040E62B = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800; LastSwiftMigration = 0900;
TestTargetID = 9B0BFFE41D0460A70040E62B; TestTargetID = 9B0BFFE41D0460A70040E62B;
}; };
9B3FFF431D09CD3B0019A709 = { 9B3FFF431D09CD3B0019A709 = {
@ -1004,7 +1004,8 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
}; };
name = Debug; name = Debug;
}; };
@ -1031,7 +1032,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG"; PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
}; };
name = Release; name = Release;
}; };
@ -1046,7 +1048,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG";
}; };
name = Debug; name = Debug;
@ -1062,7 +1065,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG";
}; };
name = Release; name = Release;

View File

@ -46,7 +46,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let kProfileMenuItemIndexBase = 100 let kProfileMenuItemIndexBase = 100
var statusItem: NSStatusItem! var statusItem: NSStatusItem!
static let StatusItemIconWidth: CGFloat = NSVariableStatusItemLength static let StatusItemIconWidth: CGFloat = NSStatusItem.variableLength
func ensureLaunchAgentsDirOwner () { func ensureLaunchAgentsDirOwner () {
let dirPath = NSHomeDirectory() + "/Library/LaunchAgents" let dirPath = NSHomeDirectory() + "/Library/LaunchAgents"
@ -104,8 +104,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
"Kcptun.Conn": NSNumber(value: 1), "Kcptun.Conn": NSNumber(value: 1),
]) ])
statusItem = NSStatusBar.system().statusItem(withLength: AppDelegate.StatusItemIconWidth) statusItem = NSStatusBar.system.statusItem(withLength: AppDelegate.StatusItemIconWidth)
let image : NSImage = NSImage(named: "menu_icon")! let image : NSImage = NSImage(named: NSImage.Name(rawValue: "menu_icon"))!
image.isTemplate = true image.isTemplate = true
statusItem.image = image statusItem.image = image
statusItem.menu = statusMenu statusItem.menu = statusMenu
@ -245,7 +245,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if editUserRulesWinCtrl != nil { if editUserRulesWinCtrl != nil {
editUserRulesWinCtrl.close() editUserRulesWinCtrl.close()
} }
let ctrl = UserRulesController(windowNibName: "UserRulesController") let ctrl = UserRulesController(windowNibName: NSNib.Name(rawValue: "UserRulesController"))
editUserRulesWinCtrl = ctrl editUserRulesWinCtrl = ctrl
ctrl.showWindow(self) ctrl.showWindow(self)
@ -261,7 +261,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if qrcodeWinCtrl != nil{ if qrcodeWinCtrl != nil{
qrcodeWinCtrl.close() qrcodeWinCtrl.close()
} }
qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: "SWBQRCodeWindowController") qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: NSNib.Name(rawValue: "SWBQRCodeWindowController"))
qrcodeWinCtrl.qrCode = profile.URL()!.absoluteString qrcodeWinCtrl.qrCode = profile.URL()!.absoluteString
qrcodeWinCtrl.legacyQRCode = profile.URL(legacy: true)!.absoluteString qrcodeWinCtrl.legacyQRCode = profile.URL(legacy: true)!.absoluteString
qrcodeWinCtrl.title = profile.title() qrcodeWinCtrl.title = profile.title()
@ -323,7 +323,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if preferencesWinCtrl != nil { if preferencesWinCtrl != nil {
preferencesWinCtrl.close() preferencesWinCtrl.close()
} }
let ctrl = PreferencesWindowController(windowNibName: "PreferencesWindowController") let ctrl = PreferencesWindowController(windowNibName: NSNib.Name(rawValue: "PreferencesWindowController"))
preferencesWinCtrl = ctrl preferencesWinCtrl = ctrl
ctrl.showWindow(self) ctrl.showWindow(self)
@ -336,7 +336,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
allInOnePreferencesWinCtrl.close() allInOnePreferencesWinCtrl.close()
} }
allInOnePreferencesWinCtrl = PreferencesWinController(windowNibName: "PreferencesWinController") allInOnePreferencesWinCtrl = PreferencesWinController(windowNibName: NSNib.Name(rawValue: "PreferencesWinController"))
allInOnePreferencesWinCtrl.showWindow(self) allInOnePreferencesWinCtrl.showWindow(self)
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
@ -366,24 +366,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let command = "export http_proxy=http://\(address):\(port);export https_proxy=http://\(address):\(port);" let command = "export http_proxy=http://\(address):\(port);export https_proxy=http://\(address):\(port);"
// Copy to paste board. // Copy to paste board.
NSPasteboard.general().clearContents() NSPasteboard.general.clearContents()
NSPasteboard.general().setString(command, forType: NSStringPboardType) NSPasteboard.general.setString(command, forType: NSPasteboard.PasteboardType.string)
// Show a toast notification. // Show a toast notification.
self.makeToast("Export Command Copied.".localized) self.makeToast("Export Command Copied.".localized)
} }
@IBAction func showLogs(_ sender: NSMenuItem) { @IBAction func showLogs(_ sender: NSMenuItem) {
let ws = NSWorkspace.shared() let ws = NSWorkspace.shared
if let appUrl = ws.urlForApplication(withBundleIdentifier: "com.apple.Console") { if let appUrl = ws.urlForApplication(withBundleIdentifier: "com.apple.Console") {
try! ws.launchApplication(at: appUrl try! ws.launchApplication(at: appUrl
,options: .default ,options: NSWorkspace.LaunchOptions.default
,configuration: [NSWorkspaceLaunchConfigurationArguments: "~/Library/Logs/ss-local.log"]) ,configuration: [NSWorkspace.LaunchConfigurationKey.arguments: "~/Library/Logs/ss-local.log"])
} }
} }
@IBAction func feedback(_ sender: NSMenuItem) { @IBAction func feedback(_ sender: NSMenuItem) {
NSWorkspace.shared().open(URL(string: "https://github.com/qiuyuzhou/ShadowsocksX-NG/issues")!) NSWorkspace.shared.open(URL(string: "https://github.com/qiuyuzhou/ShadowsocksX-NG/issues")!)
} }
@IBAction func showAbout(_ sender: NSMenuItem) { @IBAction func showAbout(_ sender: NSMenuItem) {
@ -412,17 +412,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
serversMenuItem.title = serverMenuText serversMenuItem.title = serverMenuText
if mode == "auto" { if mode == "auto" {
autoModeMenuItem.state = 1 autoModeMenuItem.state = NSControl.StateValue(rawValue: 1)
globalModeMenuItem.state = 0 globalModeMenuItem.state = NSControl.StateValue(rawValue: 0)
manualModeMenuItem.state = 0 manualModeMenuItem.state = NSControl.StateValue(rawValue: 0)
} else if mode == "global" { } else if mode == "global" {
autoModeMenuItem.state = 0 autoModeMenuItem.state = NSControl.StateValue(rawValue: 0)
globalModeMenuItem.state = 1 globalModeMenuItem.state = NSControl.StateValue(rawValue: 1)
manualModeMenuItem.state = 0 manualModeMenuItem.state = NSControl.StateValue(rawValue: 0)
} else if mode == "manual" { } else if mode == "manual" {
autoModeMenuItem.state = 0 autoModeMenuItem.state = NSControl.StateValue(rawValue: 0)
globalModeMenuItem.state = 0 globalModeMenuItem.state = NSControl.StateValue(rawValue: 0)
manualModeMenuItem.state = 1 manualModeMenuItem.state = NSControl.StateValue(rawValue: 1)
} }
updateStatusMenuImage() updateStatusMenuImage()
} }
@ -435,17 +435,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if let m = mode { if let m = mode {
switch m { switch m {
case "auto": case "auto":
statusItem.image = NSImage(named: "menu_p_icon") statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_p_icon"))
case "global": case "global":
statusItem.image = NSImage(named: "menu_g_icon") statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_g_icon"))
case "manual": case "manual":
statusItem.image = NSImage(named: "menu_m_icon") statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_m_icon"))
default: break default: break
} }
statusItem.image?.isTemplate = true statusItem.image?.isTemplate = true
} }
} else { } else {
statusItem.image = NSImage(named: "menu_icon_disabled") statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_icon_disabled"))
statusItem.image?.isTemplate = true statusItem.image?.isTemplate = true
} }
} }
@ -456,12 +456,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if isOn { if isOn {
runningStatusMenuItem.title = "Shadowsocks: On".localized runningStatusMenuItem.title = "Shadowsocks: On".localized
toggleRunningMenuItem.title = "Turn Shadowsocks Off".localized toggleRunningMenuItem.title = "Turn Shadowsocks Off".localized
let image = NSImage(named: "menu_icon") let image = NSImage(named: NSImage.Name(rawValue: "menu_icon"))
statusItem.image = image statusItem.image = image
} else { } else {
runningStatusMenuItem.title = "Shadowsocks: Off".localized runningStatusMenuItem.title = "Shadowsocks: Off".localized
toggleRunningMenuItem.title = "Turn Shadowsocks On".localized toggleRunningMenuItem.title = "Turn Shadowsocks On".localized
let image = NSImage(named: "menu_icon_disabled") let image = NSImage(named: NSImage.Name(rawValue: "menu_icon_disabled"))
statusItem.image = image statusItem.image = image
} }
statusItem.image?.isTemplate = true statusItem.image?.isTemplate = true
@ -494,7 +494,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let item = NSMenuItem() let item = NSMenuItem()
item.tag = i + kProfileMenuItemIndexBase item.tag = i + kProfileMenuItemIndexBase
item.title = profile.title() item.title = profile.title()
item.state = (mgr.activeProfileId == profile.uuid) ? 1 : 0 item.state = NSControl.StateValue(rawValue: (mgr.activeProfileId == profile.uuid) ? 1 : 0)
item.isEnabled = profile.isValid() item.isEnabled = profile.isValid()
item.action = #selector(AppDelegate.selectServer) item.action = #selector(AppDelegate.selectServer)
@ -505,7 +505,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
serverProfilesEndSeparatorMenuItem.isHidden = profiles.isEmpty serverProfilesEndSeparatorMenuItem.isHidden = profiles.isEmpty
} }
func handleURLEvent(_ event: NSAppleEventDescriptor, withReplyEvent replyEvent: NSAppleEventDescriptor) { @objc func handleURLEvent(_ event: NSAppleEventDescriptor, withReplyEvent replyEvent: NSAppleEventDescriptor) {
if let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue { if let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue {
if let url = URL(string: urlString) { if let url = URL(string: urlString) {
NotificationCenter.default.post( NotificationCenter.default.post(
@ -576,7 +576,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if toastWindowCtrl != nil { if toastWindowCtrl != nil {
toastWindowCtrl.close() toastWindowCtrl.close()
} }
toastWindowCtrl = ToastWindowController(windowNibName: "ToastWindowController") toastWindowCtrl = ToastWindowController(windowNibName: NSNib.Name(rawValue: "ToastWindowController"))
toastWindowCtrl.message = message toastWindowCtrl.message = message
toastWindowCtrl.showWindow(self) toastWindowCtrl.showWindow(self)
//NSApp.activate(ignoringOtherApps: true) //NSApp.activate(ignoringOtherApps: true)

View File

@ -19,7 +19,7 @@ class PreferencesWinController: NSWindowController {
super.windowDidLoad() super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
toolbar.selectedItemIdentifier = "general" toolbar.selectedItemIdentifier = NSToolbarItem.Identifier(rawValue: "general")
} }
func windowWillClose(_ notification: Notification) { func windowWillClose(_ notification: Notification) {

View File

@ -110,7 +110,7 @@ class PreferencesWindowController: NSWindowController
} }
override func awakeFromNib() { override func awakeFromNib() {
profilesTableView.register(forDraggedTypes: [tableViewDragType]) profilesTableView.registerForDraggedTypes([NSPasteboard.PasteboardType(rawValue: tableViewDragType)])
profilesTableView.allowsMultipleSelection = true profilesTableView.allowsMultipleSelection = true
} }
@ -125,7 +125,7 @@ class PreferencesWindowController: NSWindowController
profileMgr.profiles.append(profile) profileMgr.profiles.append(profile)
let index = IndexSet(integer: profileMgr.profiles.count-1) let index = IndexSet(integer: profileMgr.profiles.count-1)
profilesTableView.insertRows(at: index, withAnimation: .effectFade) profilesTableView.insertRows(at: index, withAnimation: NSTableView.AnimationOptions.effectFade)
self.profilesTableView.scrollRowToVisible(self.profileMgr.profiles.count-1) self.profilesTableView.scrollRowToVisible(self.profileMgr.profiles.count-1)
self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false) self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false)
@ -141,7 +141,7 @@ class PreferencesWindowController: NSWindowController
for (_, toDeleteIndex) in profilesTableView.selectedRowIndexes.enumerated() { for (_, toDeleteIndex) in profilesTableView.selectedRowIndexes.enumerated() {
print(profileMgr.profiles.count) print(profileMgr.profiles.count)
profileMgr.profiles.remove(at: toDeleteIndex - deleteCount) profileMgr.profiles.remove(at: toDeleteIndex - deleteCount)
profilesTableView.removeRows(at: IndexSet(integer: toDeleteIndex - deleteCount), withAnimation: .effectFade) profilesTableView.removeRows(at: IndexSet(integer: toDeleteIndex - deleteCount), withAnimation: NSTableView.AnimationOptions.effectFade)
deleteCount += 1 deleteCount += 1
} }
profilesTableView.endUpdates() profilesTableView.endUpdates()
@ -182,7 +182,7 @@ class PreferencesWindowController: NSWindowController
profilesTableView.beginUpdates() profilesTableView.beginUpdates()
let index = IndexSet(integer: toDuplicateIndex + copyCount) let index = IndexSet(integer: toDuplicateIndex + copyCount)
profilesTableView.insertRows(at: index, withAnimation: .effectFade) profilesTableView.insertRows(at: index, withAnimation: NSTableView.AnimationOptions.effectFade)
self.profilesTableView.scrollRowToVisible(toDuplicateIndex + copyCount) self.profilesTableView.scrollRowToVisible(toDuplicateIndex + copyCount)
self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false) self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false)
profilesTableView.endUpdates() profilesTableView.endUpdates()
@ -195,10 +195,10 @@ class PreferencesWindowController: NSWindowController
@IBAction func togglePasswordVisible(_ sender: Any) { @IBAction func togglePasswordVisible(_ sender: Any) {
if passwordTabView.selectedTabViewItem?.identifier as! String == "secure" { if passwordTabView.selectedTabViewItem?.identifier as! String == "secure" {
passwordTabView.selectTabViewItem(withIdentifier: "insecure") passwordTabView.selectTabViewItem(withIdentifier: "insecure")
togglePasswordVisibleButton.image = NSImage(named: "icons8-Eye Filled-50") togglePasswordVisibleButton.image = NSImage(named: NSImage.Name(rawValue: "icons8-Eye Filled-50"))
} else { } else {
passwordTabView.selectTabViewItem(withIdentifier: "secure") passwordTabView.selectTabViewItem(withIdentifier: "secure")
togglePasswordVisibleButton.image = NSImage(named: "icons8-Blind Filled-50") togglePasswordVisibleButton.image = NSImage(named: NSImage.Name(rawValue: "icons8-Blind Filled-50"))
} }
} }
@ -210,7 +210,7 @@ class PreferencesWindowController: NSWindowController
if let url = ssURL { if let url = ssURL {
// Then copy url to pasteboard // Then copy url to pasteboard
// TODO Why it not working?? It's ok in objective-c // TODO Why it not working?? It's ok in objective-c
let pboard = NSPasteboard.general() let pboard = NSPasteboard.general
pboard.clearContents() pboard.clearContents()
let rs = pboard.writeObjects([url as NSPasteboardWriting]) let rs = pboard.writeObjects([url as NSPasteboardWriting])
if rs { if rs {
@ -253,70 +253,70 @@ class PreferencesWindowController: NSWindowController
} }
}) })
hostTextField.bind("value", to: editingProfile, withKeyPath: "serverHost" hostTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverHost"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
portTextField.bind("value", to: editingProfile, withKeyPath: "serverPort" portTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverPort"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
methodTextField.bind("value", to: editingProfile, withKeyPath: "method" methodTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "method"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
passwordTextField.bind("value", to: editingProfile, withKeyPath: "password" passwordTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "password"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
passwordSecureTextField.bind("value", to: editingProfile, withKeyPath: "password" passwordSecureTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "password"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
remarkTextField.bind("value", to: editingProfile, withKeyPath: "remark" remarkTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "remark"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
otaCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "ota" otaCheckBoxBtn.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "ota"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
// -------------------------------------------------- // --------------------------------------------------
// Kcptun // Kcptun
kcptunCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "enabledKcptun" kcptunCheckBoxBtn.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "enabledKcptun"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunPortTextField.bind("value", to: editingProfile, withKeyPath: "serverPort" kcptunPortTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverPort"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunProfileBox.bind("Hidden", to: editingProfile, withKeyPath: "enabledKcptun" kcptunProfileBox.bind(NSBindingName(rawValue: "Hidden"), to: editingProfile, withKeyPath: "enabledKcptun"
, options: [NSContinuouslyUpdatesValueBindingOption: false, , options: [NSBindingOption.continuouslyUpdatesValue: false,
NSValueTransformerNameBindingOption: NSValueTransformerName.negateBooleanTransformerName]) NSBindingOption.valueTransformerName: NSValueTransformerName.negateBooleanTransformerName])
kcptunNocompCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.nocomp", options: nil) kcptunNocompCheckBoxBtn.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.nocomp", options: nil)
kcptunModeComboBox.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.mode", options: nil) kcptunModeComboBox.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.mode", options: nil)
kcptunCryptComboBox.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.crypt", options: nil) kcptunCryptComboBox.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.crypt", options: nil)
kcptunKeyTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.key" kcptunKeyTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.key"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunDatashardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.datashard" kcptunDatashardTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.datashard"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunParityshardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.parityshard" kcptunParityshardTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.parityshard"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunMTUTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.mtu" kcptunMTUTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.mtu"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
kcptunArgumentsTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.arguments" kcptunArgumentsTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.arguments"
, options: [NSContinuouslyUpdatesValueBindingOption: true]) , options: [NSBindingOption.continuouslyUpdatesValue: true])
} else { } else {
editingProfile = nil editingProfile = nil
hostTextField.unbind("value") hostTextField.unbind(NSBindingName(rawValue: "value"))
portTextField.unbind("value") portTextField.unbind(NSBindingName(rawValue: "value"))
methodTextField.unbind("value") methodTextField.unbind(NSBindingName(rawValue: "value"))
passwordTextField.unbind("value") passwordTextField.unbind(NSBindingName(rawValue: "value"))
remarkTextField.unbind("value") remarkTextField.unbind(NSBindingName(rawValue: "value"))
otaCheckBoxBtn.unbind("value") otaCheckBoxBtn.unbind(NSBindingName(rawValue: "value"))
kcptunCheckBoxBtn.unbind("value") kcptunCheckBoxBtn.unbind(NSBindingName(rawValue: "value"))
} }
} }
@ -346,11 +346,11 @@ class PreferencesWindowController: NSWindowController
let (title, isActive) = getDataAtRow(row) let (title, isActive) = getDataAtRow(row)
if tableColumn?.identifier == "main" { if tableColumn?.identifier == NSUserInterfaceItemIdentifier("main") {
return title return title
} else if tableColumn?.identifier == "status" { } else if tableColumn?.identifier == NSUserInterfaceItemIdentifier("status") {
if isActive { if isActive {
return NSImage(named: "NSMenuOnStateTemplate") return NSImage(named: NSImage.Name(rawValue: "NSMenuOnStateTemplate"))
} else { } else {
return nil return nil
} }
@ -362,12 +362,12 @@ class PreferencesWindowController: NSWindowController
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? { func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem() let item = NSPasteboardItem()
item.setString(String(row), forType: tableViewDragType) item.setString(String(row), forType: NSPasteboard.PasteboardType(rawValue: tableViewDragType))
return item return item
} }
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int
, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation { , proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
if dropOperation == .above { if dropOperation == .above {
return .move return .move
} }
@ -375,14 +375,15 @@ class PreferencesWindowController: NSWindowController
} }
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo
, row: Int, dropOperation: NSTableViewDropOperation) -> Bool { , row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
if let mgr = profileMgr { if let mgr = profileMgr {
var oldIndexes = [Int]() var oldIndexes = [Int]()
info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) { info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:], using: {
if let str = ($0.0.item as! NSPasteboardItem).string(forType: self.tableViewDragType), let index = Int(str) { (draggingItem: NSDraggingItem, idx: Int, stop: UnsafeMutablePointer<ObjCBool>) in
if let str = (draggingItem.item as! NSPasteboardItem).string(forType: NSPasteboard.PasteboardType(rawValue: self.tableViewDragType)), let index = Int(str) {
oldIndexes.append(index) oldIndexes.append(index)
} }
} })
var oldIndexOffset = 0 var oldIndexOffset = 0
var newIndexOffset = 0 var newIndexOffset = 0
@ -462,7 +463,7 @@ class PreferencesWindowController: NSWindowController
shakePath.closeSubpath() shakePath.closeSubpath()
shakeAnimation.path = shakePath shakeAnimation.path = shakePath
shakeAnimation.duration = CFTimeInterval(durationOfShake) shakeAnimation.duration = CFTimeInterval(durationOfShake)
window?.animations = ["frameOrigin":shakeAnimation] window?.animations = [NSAnimatablePropertyKey(rawValue: "frameOrigin"):shakeAnimation]
window?.animator().setFrameOrigin(window!.frame.origin) window?.animator().setFrameOrigin(window!.frame.origin)
} }
} }

View File

@ -48,9 +48,9 @@ class ProxyInterfacesViewCtrl: NSViewController, NSTableViewDataSource, NSTableV
let networkService = networkServices[row] as! [String: Any] let networkService = networkServices[row] as! [String: Any]
let key = networkService["key"] as! String let key = networkService["key"] as! String
if selectedNetworkServices.contains(key) { if selectedNetworkServices.contains(key) {
cell.state = 1 cell.state = NSControl.StateValue(rawValue: 1)
} else { } else {
cell.state = 0 cell.state = NSControl.StateValue(rawValue: 0)
} }
let userDefinedName = networkService["userDefinedName"] as! String let userDefinedName = networkService["userDefinedName"] as! String
cell.title = userDefinedName cell.title = userDefinedName

View File

@ -47,8 +47,8 @@ class ServerProfile: NSObject, NSCopying {
func decodeUrl(url: URL) -> String? { func decodeUrl(url: URL) -> String? {
let urlStr = url.absoluteString let urlStr = url.absoluteString
let index = urlStr.index(urlStr.startIndex, offsetBy: 5) let index = urlStr.index(urlStr.startIndex, offsetBy: 5)
let encodedStr = urlStr.substring(from: index) let encodedStr = urlStr[index...]
guard let data = Data(base64Encoded: padBase64(string: encodedStr)) else { guard let data = Data(base64Encoded: padBase64(string: String(encodedStr))) else {
return url.absoluteString return url.absoluteString
} }
guard let decoded = String(data: data, encoding: String.Encoding.utf8) else { guard let decoded = String(data: data, encoding: String.Encoding.utf8) else {

View File

@ -80,7 +80,7 @@ class ServerProfileManager: NSObject {
openPanel.canChooseFiles = true openPanel.canChooseFiles = true
openPanel.becomeKey() openPanel.becomeKey()
let result = openPanel.runModal() let result = openPanel.runModal()
if (result == NSFileHandlingPanelOKButton && (openPanel.url) != nil) { if (result.rawValue == NSFileHandlingPanelOKButton && (openPanel.url) != nil) {
let fileManager = FileManager.default let fileManager = FileManager.default
let filePath:String = (openPanel.url?.path)! let filePath:String = (openPanel.url?.path)!
if (fileManager.fileExists(atPath: filePath) && filePath.hasSuffix("json")) { if (fileManager.fileExists(atPath: filePath) && filePath.hasSuffix("json")) {
@ -164,10 +164,10 @@ class ServerProfileManager: NSObject {
savePanel.nameFieldStringValue = "export.json" savePanel.nameFieldStringValue = "export.json"
savePanel.becomeKey() savePanel.becomeKey()
let result = savePanel.runModal() let result = savePanel.runModal()
if (result == NSFileHandlingPanelOKButton && (savePanel.url) != nil) { if (result.rawValue == NSFileHandlingPanelOKButton && (savePanel.url) != nil) {
//write jsonArr1 back to file //write jsonArr1 back to file
try! jsonString.write(toFile: (savePanel.url?.path)!, atomically: true, encoding: String.Encoding.utf8) try! jsonString.write(toFile: (savePanel.url?.path)!, atomically: true, encoding: String.Encoding.utf8)
NSWorkspace.shared().selectFile((savePanel.url?.path)!, inFileViewerRootedAtPath: (savePanel.directoryURL?.path)!) NSWorkspace.shared.selectFile((savePanel.url?.path)!, inFileViewerRootedAtPath: (savePanel.directoryURL?.path)!)
let notification = NSUserNotification() let notification = NSUserNotification()
notification.title = "Export Server Profile succeed!".localized notification.title = "Export Server Profile succeed!".localized
notification.informativeText = "Successful Export \(self.profiles.count) items".localized notification.informativeText = "Successful Export \(self.profiles.count) items".localized
@ -184,10 +184,10 @@ class ServerProfileManager: NSObject {
let destPath = dataPath + "/example-gui-config.json" let destPath = dataPath + "/example-gui-config.json"
//sharedWorkspace //sharedWorkspace
if fileMgr.fileExists(atPath: destPath) { if fileMgr.fileExists(atPath: destPath) {
NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) NSWorkspace.shared.selectFile(destPath, inFileViewerRootedAtPath: dataPath)
}else{ }else{
try! fileMgr.copyItem(atPath: filePath, toPath: destPath) try! fileMgr.copyItem(atPath: filePath, toPath: destPath)
NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) NSWorkspace.shared.selectFile(destPath, inFileViewerRootedAtPath: dataPath)
} }
} }
} }

View File

@ -36,10 +36,10 @@ class ToastWindowController: NSWindowController {
if let win = self.window { if let win = self.window {
win.isOpaque = false win.isOpaque = false
win.backgroundColor = .clear win.backgroundColor = .clear
win.styleMask = .borderless win.styleMask = NSWindow.StyleMask.borderless
win.hidesOnDeactivate = false win.hidesOnDeactivate = false
win.collectionBehavior = .canJoinAllSpaces win.collectionBehavior = NSWindow.CollectionBehavior.canJoinAllSpaces
win.level = Int(CGWindowLevelForKey(.floatingWindow)) win.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.floatingWindow)))
win.orderFrontRegardless() win.orderFrontRegardless()
} }
@ -63,7 +63,7 @@ class ToastWindowController: NSWindowController {
hudWindowFrame.size.width = labelFrame.size.width + kHudHorizontalMargin * 2 hudWindowFrame.size.width = labelFrame.size.width + kHudHorizontalMargin * 2
hudWindowFrame.size.height = kHudHeight hudWindowFrame.size.height = kHudHeight
let screenRect: NSRect = NSScreen.screens()![0].visibleFrame let screenRect: NSRect = NSScreen.screens[0].visibleFrame
hudWindowFrame.origin.x = (screenRect.size.width - hudWindowFrame.size.width) / 2 hudWindowFrame.origin.x = (screenRect.size.width - hudWindowFrame.size.width) / 2
hudWindowFrame.origin.y = (screenRect.size.height - hudWindowFrame.size.height) / 2 hudWindowFrame.origin.y = (screenRect.size.height - hudWindowFrame.size.height) / 2
self.window!.setFrame(hudWindowFrame, display: true) self.window!.setFrame(hudWindowFrame, display: true)
@ -102,7 +102,7 @@ class ToastWindowController: NSWindowController {
repeats: false) repeats: false)
} }
func fadeOutHud() -> Void { @objc func fadeOutHud() -> Void {
fadingOut = true fadingOut = true
CATransaction.begin() CATransaction.begin()

View File

@ -22,7 +22,7 @@ class UserRulesController: NSWindowController {
} }
let str = try? String(contentsOfFile: PACUserRuleFilePath, encoding: String.Encoding.utf8) let str = try? String(contentsOfFile: PACUserRuleFilePath, encoding: String.Encoding.utf8)
userRulesView.string = str userRulesView.string = str!
} }
@IBAction func didCancel(_ sender: AnyObject) { @IBAction func didCancel(_ sender: AnyObject) {
@ -30,7 +30,7 @@ class UserRulesController: NSWindowController {
} }
@IBAction func didOK(_ sender: AnyObject) { @IBAction func didOK(_ sender: AnyObject) {
if let str = userRulesView.string { if let str = userRulesView?.string {
do { do {
try str.data(using: String.Encoding.utf8)?.write(to: URL(fileURLWithPath: PACUserRuleFilePath), options: .atomic) try str.data(using: String.Encoding.utf8)?.write(to: URL(fileURLWithPath: PACUserRuleFilePath), options: .atomic)