From d56b108eb8a8087337b2c9c9ccc6743f5f9944a9 Mon Sep 17 00:00:00 2001 From: Qiu Yuzhou Date: Fri, 20 Oct 2017 18:39:25 +0800 Subject: [PATCH] Conversion to Swift 4. --- ShadowsocksX-NG.xcodeproj/project.pbxproj | 16 ++- ShadowsocksX-NG/AppDelegate.swift | 62 +++++----- .../PreferencesWinController.swift | 2 +- .../PreferencesWindowController.swift | 117 +++++++++--------- ShadowsocksX-NG/ProxyInterfacesViewCtrl.swift | 4 +- ShadowsocksX-NG/ServerProfile.swift | 4 +- ShadowsocksX-NG/ServerProfileManager.swift | 10 +- ShadowsocksX-NG/ToastWindowController.swift | 10 +- ShadowsocksX-NG/UserRulesController.swift | 4 +- 9 files changed, 117 insertions(+), 112 deletions(-) diff --git a/ShadowsocksX-NG.xcodeproj/project.pbxproj b/ShadowsocksX-NG.xcodeproj/project.pbxproj index 3ecda5a..f6103cc 100755 --- a/ShadowsocksX-NG.xcodeproj/project.pbxproj +++ b/ShadowsocksX-NG.xcodeproj/project.pbxproj @@ -532,11 +532,11 @@ TargetAttributes = { 9B0BFFE41D0460A70040E62B = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; 9B0BFFF31D0460A70040E62B = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; TestTargetID = 9B0BFFE41D0460A70040E62B; }; 9B3FFF431D09CD3B0019A709 = { @@ -1004,7 +1004,8 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -1031,7 +1032,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG"; PRODUCT_NAME = "$(TARGET_NAME)"; 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; }; @@ -1046,7 +1048,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_NAME = "$(TARGET_NAME)"; 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"; }; name = Debug; @@ -1062,7 +1065,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_NAME = "$(TARGET_NAME)"; 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"; }; name = Release; diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index c58f0b3..66258e5 100755 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -46,7 +46,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele let kProfileMenuItemIndexBase = 100 var statusItem: NSStatusItem! - static let StatusItemIconWidth: CGFloat = NSVariableStatusItemLength + static let StatusItemIconWidth: CGFloat = NSStatusItem.variableLength func ensureLaunchAgentsDirOwner () { let dirPath = NSHomeDirectory() + "/Library/LaunchAgents" @@ -104,8 +104,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele "Kcptun.Conn": NSNumber(value: 1), ]) - statusItem = NSStatusBar.system().statusItem(withLength: AppDelegate.StatusItemIconWidth) - let image : NSImage = NSImage(named: "menu_icon")! + statusItem = NSStatusBar.system.statusItem(withLength: AppDelegate.StatusItemIconWidth) + let image : NSImage = NSImage(named: NSImage.Name(rawValue: "menu_icon"))! image.isTemplate = true statusItem.image = image statusItem.menu = statusMenu @@ -245,7 +245,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if editUserRulesWinCtrl != nil { editUserRulesWinCtrl.close() } - let ctrl = UserRulesController(windowNibName: "UserRulesController") + let ctrl = UserRulesController(windowNibName: NSNib.Name(rawValue: "UserRulesController")) editUserRulesWinCtrl = ctrl ctrl.showWindow(self) @@ -261,7 +261,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if qrcodeWinCtrl != nil{ qrcodeWinCtrl.close() } - qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: "SWBQRCodeWindowController") + qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: NSNib.Name(rawValue: "SWBQRCodeWindowController")) qrcodeWinCtrl.qrCode = profile.URL()!.absoluteString qrcodeWinCtrl.legacyQRCode = profile.URL(legacy: true)!.absoluteString qrcodeWinCtrl.title = profile.title() @@ -323,7 +323,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if preferencesWinCtrl != nil { preferencesWinCtrl.close() } - let ctrl = PreferencesWindowController(windowNibName: "PreferencesWindowController") + let ctrl = PreferencesWindowController(windowNibName: NSNib.Name(rawValue: "PreferencesWindowController")) preferencesWinCtrl = ctrl ctrl.showWindow(self) @@ -336,7 +336,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele allInOnePreferencesWinCtrl.close() } - allInOnePreferencesWinCtrl = PreferencesWinController(windowNibName: "PreferencesWinController") + allInOnePreferencesWinCtrl = PreferencesWinController(windowNibName: NSNib.Name(rawValue: "PreferencesWinController")) allInOnePreferencesWinCtrl.showWindow(self) 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);" // Copy to paste board. - NSPasteboard.general().clearContents() - NSPasteboard.general().setString(command, forType: NSStringPboardType) + NSPasteboard.general.clearContents() + NSPasteboard.general.setString(command, forType: NSPasteboard.PasteboardType.string) // Show a toast notification. self.makeToast("Export Command Copied.".localized) } @IBAction func showLogs(_ sender: NSMenuItem) { - let ws = NSWorkspace.shared() + let ws = NSWorkspace.shared if let appUrl = ws.urlForApplication(withBundleIdentifier: "com.apple.Console") { try! ws.launchApplication(at: appUrl - ,options: .default - ,configuration: [NSWorkspaceLaunchConfigurationArguments: "~/Library/Logs/ss-local.log"]) + ,options: NSWorkspace.LaunchOptions.default + ,configuration: [NSWorkspace.LaunchConfigurationKey.arguments: "~/Library/Logs/ss-local.log"]) } } @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) { @@ -412,17 +412,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele serversMenuItem.title = serverMenuText if mode == "auto" { - autoModeMenuItem.state = 1 - globalModeMenuItem.state = 0 - manualModeMenuItem.state = 0 + autoModeMenuItem.state = NSControl.StateValue(rawValue: 1) + globalModeMenuItem.state = NSControl.StateValue(rawValue: 0) + manualModeMenuItem.state = NSControl.StateValue(rawValue: 0) } else if mode == "global" { - autoModeMenuItem.state = 0 - globalModeMenuItem.state = 1 - manualModeMenuItem.state = 0 + autoModeMenuItem.state = NSControl.StateValue(rawValue: 0) + globalModeMenuItem.state = NSControl.StateValue(rawValue: 1) + manualModeMenuItem.state = NSControl.StateValue(rawValue: 0) } else if mode == "manual" { - autoModeMenuItem.state = 0 - globalModeMenuItem.state = 0 - manualModeMenuItem.state = 1 + autoModeMenuItem.state = NSControl.StateValue(rawValue: 0) + globalModeMenuItem.state = NSControl.StateValue(rawValue: 0) + manualModeMenuItem.state = NSControl.StateValue(rawValue: 1) } updateStatusMenuImage() } @@ -435,17 +435,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if let m = mode { switch m { case "auto": - statusItem.image = NSImage(named: "menu_p_icon") + statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_p_icon")) case "global": - statusItem.image = NSImage(named: "menu_g_icon") + statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_g_icon")) case "manual": - statusItem.image = NSImage(named: "menu_m_icon") + statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_m_icon")) default: break } statusItem.image?.isTemplate = true } } else { - statusItem.image = NSImage(named: "menu_icon_disabled") + statusItem.image = NSImage(named: NSImage.Name(rawValue: "menu_icon_disabled")) statusItem.image?.isTemplate = true } } @@ -456,12 +456,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if isOn { runningStatusMenuItem.title = "Shadowsocks: On".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 } else { runningStatusMenuItem.title = "Shadowsocks: Off".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?.isTemplate = true @@ -494,7 +494,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele let item = NSMenuItem() item.tag = i + kProfileMenuItemIndexBase 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.action = #selector(AppDelegate.selectServer) @@ -505,7 +505,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele 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 url = URL(string: urlString) { NotificationCenter.default.post( @@ -576,7 +576,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if toastWindowCtrl != nil { toastWindowCtrl.close() } - toastWindowCtrl = ToastWindowController(windowNibName: "ToastWindowController") + toastWindowCtrl = ToastWindowController(windowNibName: NSNib.Name(rawValue: "ToastWindowController")) toastWindowCtrl.message = message toastWindowCtrl.showWindow(self) //NSApp.activate(ignoringOtherApps: true) diff --git a/ShadowsocksX-NG/PreferencesWinController.swift b/ShadowsocksX-NG/PreferencesWinController.swift index 74a3746..5b4291a 100644 --- a/ShadowsocksX-NG/PreferencesWinController.swift +++ b/ShadowsocksX-NG/PreferencesWinController.swift @@ -19,7 +19,7 @@ class PreferencesWinController: NSWindowController { super.windowDidLoad() // 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) { diff --git a/ShadowsocksX-NG/PreferencesWindowController.swift b/ShadowsocksX-NG/PreferencesWindowController.swift index b9a5ecf..21b3951 100644 --- a/ShadowsocksX-NG/PreferencesWindowController.swift +++ b/ShadowsocksX-NG/PreferencesWindowController.swift @@ -110,7 +110,7 @@ class PreferencesWindowController: NSWindowController } override func awakeFromNib() { - profilesTableView.register(forDraggedTypes: [tableViewDragType]) + profilesTableView.registerForDraggedTypes([NSPasteboard.PasteboardType(rawValue: tableViewDragType)]) profilesTableView.allowsMultipleSelection = true } @@ -125,7 +125,7 @@ class PreferencesWindowController: NSWindowController profileMgr.profiles.append(profile) 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.selectRowIndexes(index, byExtendingSelection: false) @@ -141,7 +141,7 @@ class PreferencesWindowController: NSWindowController for (_, toDeleteIndex) in profilesTableView.selectedRowIndexes.enumerated() { print(profileMgr.profiles.count) 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 } profilesTableView.endUpdates() @@ -182,7 +182,7 @@ class PreferencesWindowController: NSWindowController profilesTableView.beginUpdates() 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.selectRowIndexes(index, byExtendingSelection: false) profilesTableView.endUpdates() @@ -195,10 +195,10 @@ class PreferencesWindowController: NSWindowController @IBAction func togglePasswordVisible(_ sender: Any) { if passwordTabView.selectedTabViewItem?.identifier as! String == "secure" { passwordTabView.selectTabViewItem(withIdentifier: "insecure") - togglePasswordVisibleButton.image = NSImage(named: "icons8-Eye Filled-50") + togglePasswordVisibleButton.image = NSImage(named: NSImage.Name(rawValue: "icons8-Eye Filled-50")) } else { 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 { // Then copy url to pasteboard // TODO Why it not working?? It's ok in objective-c - let pboard = NSPasteboard.general() + let pboard = NSPasteboard.general pboard.clearContents() let rs = pboard.writeObjects([url as NSPasteboardWriting]) if rs { @@ -253,70 +253,70 @@ class PreferencesWindowController: NSWindowController } }) - hostTextField.bind("value", to: editingProfile, withKeyPath: "serverHost" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) - portTextField.bind("value", to: editingProfile, withKeyPath: "serverPort" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + hostTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverHost" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) + portTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverPort" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - methodTextField.bind("value", to: editingProfile, withKeyPath: "method" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) - passwordTextField.bind("value", to: editingProfile, withKeyPath: "password" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) - passwordSecureTextField.bind("value", to: editingProfile, withKeyPath: "password" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + methodTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "method" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) + passwordTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "password" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) + passwordSecureTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "password" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - remarkTextField.bind("value", to: editingProfile, withKeyPath: "remark" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + remarkTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "remark" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - otaCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "ota" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + otaCheckBoxBtn.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "ota" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) // -------------------------------------------------- // Kcptun - kcptunCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "enabledKcptun" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunCheckBoxBtn.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "enabledKcptun" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunPortTextField.bind("value", to: editingProfile, withKeyPath: "serverPort" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunPortTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "serverPort" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunProfileBox.bind("Hidden", to: editingProfile, withKeyPath: "enabledKcptun" - , options: [NSContinuouslyUpdatesValueBindingOption: false, - NSValueTransformerNameBindingOption: NSValueTransformerName.negateBooleanTransformerName]) + kcptunProfileBox.bind(NSBindingName(rawValue: "Hidden"), to: editingProfile, withKeyPath: "enabledKcptun" + , options: [NSBindingOption.continuouslyUpdatesValue: false, + 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" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunKeyTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.key" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunDatashardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.datashard" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunDatashardTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.datashard" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunParityshardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.parityshard" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunParityshardTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.parityshard" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunMTUTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.mtu" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunMTUTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.mtu" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) - kcptunArgumentsTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.arguments" - , options: [NSContinuouslyUpdatesValueBindingOption: true]) + kcptunArgumentsTextField.bind(NSBindingName(rawValue: "value"), to: editingProfile, withKeyPath: "kcptunProfile.arguments" + , options: [NSBindingOption.continuouslyUpdatesValue: true]) } else { editingProfile = nil - hostTextField.unbind("value") - portTextField.unbind("value") + hostTextField.unbind(NSBindingName(rawValue: "value")) + portTextField.unbind(NSBindingName(rawValue: "value")) - methodTextField.unbind("value") - passwordTextField.unbind("value") + methodTextField.unbind(NSBindingName(rawValue: "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) - if tableColumn?.identifier == "main" { + if tableColumn?.identifier == NSUserInterfaceItemIdentifier("main") { return title - } else if tableColumn?.identifier == "status" { + } else if tableColumn?.identifier == NSUserInterfaceItemIdentifier("status") { if isActive { - return NSImage(named: "NSMenuOnStateTemplate") + return NSImage(named: NSImage.Name(rawValue: "NSMenuOnStateTemplate")) } else { return nil } @@ -362,12 +362,12 @@ class PreferencesWindowController: NSWindowController func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? { let item = NSPasteboardItem() - item.setString(String(row), forType: tableViewDragType) + item.setString(String(row), forType: NSPasteboard.PasteboardType(rawValue: tableViewDragType)) return item } func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int - , proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation { + , proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation { if dropOperation == .above { return .move } @@ -375,14 +375,15 @@ class PreferencesWindowController: NSWindowController } func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo - , row: Int, dropOperation: NSTableViewDropOperation) -> Bool { + , row: Int, dropOperation: NSTableView.DropOperation) -> Bool { if let mgr = profileMgr { var oldIndexes = [Int]() - info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) { - if let str = ($0.0.item as! NSPasteboardItem).string(forType: self.tableViewDragType), let index = Int(str) { + info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:], using: { + (draggingItem: NSDraggingItem, idx: Int, stop: UnsafeMutablePointer) in + if let str = (draggingItem.item as! NSPasteboardItem).string(forType: NSPasteboard.PasteboardType(rawValue: self.tableViewDragType)), let index = Int(str) { oldIndexes.append(index) } - } + }) var oldIndexOffset = 0 var newIndexOffset = 0 @@ -462,7 +463,7 @@ class PreferencesWindowController: NSWindowController shakePath.closeSubpath() shakeAnimation.path = shakePath shakeAnimation.duration = CFTimeInterval(durationOfShake) - window?.animations = ["frameOrigin":shakeAnimation] + window?.animations = [NSAnimatablePropertyKey(rawValue: "frameOrigin"):shakeAnimation] window?.animator().setFrameOrigin(window!.frame.origin) } } diff --git a/ShadowsocksX-NG/ProxyInterfacesViewCtrl.swift b/ShadowsocksX-NG/ProxyInterfacesViewCtrl.swift index 6173794..7512279 100644 --- a/ShadowsocksX-NG/ProxyInterfacesViewCtrl.swift +++ b/ShadowsocksX-NG/ProxyInterfacesViewCtrl.swift @@ -48,9 +48,9 @@ class ProxyInterfacesViewCtrl: NSViewController, NSTableViewDataSource, NSTableV let networkService = networkServices[row] as! [String: Any] let key = networkService["key"] as! String if selectedNetworkServices.contains(key) { - cell.state = 1 + cell.state = NSControl.StateValue(rawValue: 1) } else { - cell.state = 0 + cell.state = NSControl.StateValue(rawValue: 0) } let userDefinedName = networkService["userDefinedName"] as! String cell.title = userDefinedName diff --git a/ShadowsocksX-NG/ServerProfile.swift b/ShadowsocksX-NG/ServerProfile.swift index ec939db..d7929fd 100644 --- a/ShadowsocksX-NG/ServerProfile.swift +++ b/ShadowsocksX-NG/ServerProfile.swift @@ -47,8 +47,8 @@ class ServerProfile: NSObject, NSCopying { func decodeUrl(url: URL) -> String? { let urlStr = url.absoluteString let index = urlStr.index(urlStr.startIndex, offsetBy: 5) - let encodedStr = urlStr.substring(from: index) - guard let data = Data(base64Encoded: padBase64(string: encodedStr)) else { + let encodedStr = urlStr[index...] + guard let data = Data(base64Encoded: padBase64(string: String(encodedStr))) else { return url.absoluteString } guard let decoded = String(data: data, encoding: String.Encoding.utf8) else { diff --git a/ShadowsocksX-NG/ServerProfileManager.swift b/ShadowsocksX-NG/ServerProfileManager.swift index b0c8467..e06ea00 100644 --- a/ShadowsocksX-NG/ServerProfileManager.swift +++ b/ShadowsocksX-NG/ServerProfileManager.swift @@ -80,7 +80,7 @@ class ServerProfileManager: NSObject { openPanel.canChooseFiles = true openPanel.becomeKey() let result = openPanel.runModal() - if (result == NSFileHandlingPanelOKButton && (openPanel.url) != nil) { + if (result.rawValue == NSFileHandlingPanelOKButton && (openPanel.url) != nil) { let fileManager = FileManager.default let filePath:String = (openPanel.url?.path)! if (fileManager.fileExists(atPath: filePath) && filePath.hasSuffix("json")) { @@ -164,10 +164,10 @@ class ServerProfileManager: NSObject { savePanel.nameFieldStringValue = "export.json" savePanel.becomeKey() let result = savePanel.runModal() - if (result == NSFileHandlingPanelOKButton && (savePanel.url) != nil) { + if (result.rawValue == NSFileHandlingPanelOKButton && (savePanel.url) != nil) { //write jsonArr1 back to file 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() notification.title = "Export Server Profile succeed!".localized notification.informativeText = "Successful Export \(self.profiles.count) items".localized @@ -184,10 +184,10 @@ class ServerProfileManager: NSObject { let destPath = dataPath + "/example-gui-config.json" //检测文件是否已经存在,如果存在直接用sharedWorkspace显示 if fileMgr.fileExists(atPath: destPath) { - NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) + NSWorkspace.shared.selectFile(destPath, inFileViewerRootedAtPath: dataPath) }else{ try! fileMgr.copyItem(atPath: filePath, toPath: destPath) - NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) + NSWorkspace.shared.selectFile(destPath, inFileViewerRootedAtPath: dataPath) } } } diff --git a/ShadowsocksX-NG/ToastWindowController.swift b/ShadowsocksX-NG/ToastWindowController.swift index 161a105..8d35477 100644 --- a/ShadowsocksX-NG/ToastWindowController.swift +++ b/ShadowsocksX-NG/ToastWindowController.swift @@ -36,10 +36,10 @@ class ToastWindowController: NSWindowController { if let win = self.window { win.isOpaque = false win.backgroundColor = .clear - win.styleMask = .borderless + win.styleMask = NSWindow.StyleMask.borderless win.hidesOnDeactivate = false - win.collectionBehavior = .canJoinAllSpaces - win.level = Int(CGWindowLevelForKey(.floatingWindow)) + win.collectionBehavior = NSWindow.CollectionBehavior.canJoinAllSpaces + win.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.floatingWindow))) win.orderFrontRegardless() } @@ -63,7 +63,7 @@ class ToastWindowController: NSWindowController { hudWindowFrame.size.width = labelFrame.size.width + kHudHorizontalMargin * 2 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.y = (screenRect.size.height - hudWindowFrame.size.height) / 2 self.window!.setFrame(hudWindowFrame, display: true) @@ -102,7 +102,7 @@ class ToastWindowController: NSWindowController { repeats: false) } - func fadeOutHud() -> Void { + @objc func fadeOutHud() -> Void { fadingOut = true CATransaction.begin() diff --git a/ShadowsocksX-NG/UserRulesController.swift b/ShadowsocksX-NG/UserRulesController.swift index f378ca3..9a5ef87 100644 --- a/ShadowsocksX-NG/UserRulesController.swift +++ b/ShadowsocksX-NG/UserRulesController.swift @@ -22,7 +22,7 @@ class UserRulesController: NSWindowController { } let str = try? String(contentsOfFile: PACUserRuleFilePath, encoding: String.Encoding.utf8) - userRulesView.string = str + userRulesView.string = str! } @IBAction func didCancel(_ sender: AnyObject) { @@ -30,7 +30,7 @@ class UserRulesController: NSWindowController { } @IBAction func didOK(_ sender: AnyObject) { - if let str = userRulesView.string { + if let str = userRulesView?.string { do { try str.data(using: String.Encoding.utf8)?.write(to: URL(fileURLWithPath: PACUserRuleFilePath), options: .atomic)