From c8f85ffec97206174dbffbf6290ebcdcf84355ac Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 16 Jun 2016 20:53:55 -0700 Subject: [PATCH] Factored network updates into its own class. Delivered via notification --- ZeroTier One.xcodeproj/project.pbxproj | 4 + ZeroTier One/AppDelegate.swift | 12 +- ZeroTier One/Info.plist | 2 +- ZeroTier One/NetworkMonitor.swift | 116 ++++++++++++++++++ ZeroTier One/ServiceCom.swift | 5 + ZeroTier One/ShowNetworksViewController.swift | 87 ++----------- 6 files changed, 145 insertions(+), 81 deletions(-) create mode 100644 ZeroTier One/NetworkMonitor.swift diff --git a/ZeroTier One.xcodeproj/project.pbxproj b/ZeroTier One.xcodeproj/project.pbxproj index 0a8188c99..ed054cb4c 100644 --- a/ZeroTier One.xcodeproj/project.pbxproj +++ b/ZeroTier One.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 932D472D1D138B0C004BCFE2 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932D472C1D138B0C004BCFE2 /* NetworkMonitor.swift */; }; 9330F1351CEAB4C400687EC8 /* ServiceCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F1341CEAB4C400687EC8 /* ServiceCom.swift */; }; 9330F1371CEBF87200687EC8 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F1361CEBF87200687EC8 /* Network.swift */; }; 9330F13B1CF534E500687EC8 /* NetworkInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F13A1CF534E500687EC8 /* NetworkInfoCell.swift */; }; @@ -21,6 +22,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 932D472C1D138B0C004BCFE2 /* NetworkMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = ""; }; 9330F1341CEAB4C400687EC8 /* ServiceCom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceCom.swift; sourceTree = ""; }; 9330F1361CEBF87200687EC8 /* Network.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; 9330F13A1CF534E500687EC8 /* NetworkInfoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkInfoCell.swift; sourceTree = ""; }; @@ -82,6 +84,7 @@ 93DAFE4A1CFE53CA00547CC4 /* AuthtokenCopy.m */, 93DAFE4C1CFE53DA00547CC4 /* AuthtokenCopy.h */, 93DAFE491CFE53C900547CC4 /* ZeroTier One-Bridging-Header.h */, + 932D472C1D138B0C004BCFE2 /* NetworkMonitor.swift */, ); path = "ZeroTier One"; sourceTree = ""; @@ -159,6 +162,7 @@ buildActionMask = 2147483647; files = ( 9330F1371CEBF87200687EC8 /* Network.swift in Sources */, + 932D472D1D138B0C004BCFE2 /* NetworkMonitor.swift in Sources */, 93326BDC1CE7C816005CA2AC /* AppDelegate.swift in Sources */, 93DAFE4B1CFE53CA00547CC4 /* AuthtokenCopy.m in Sources */, 9330F13B1CF534E500687EC8 /* NetworkInfoCell.swift in Sources */, diff --git a/ZeroTier One/AppDelegate.swift b/ZeroTier One/AppDelegate.swift index c7cbc09ac..f0bd04375 100644 --- a/ZeroTier One/AppDelegate.swift +++ b/ZeroTier One/AppDelegate.swift @@ -21,8 +21,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { var transientMonitor: AnyObject? = nil - func applicationDidFinishLaunching(aNotification: NSNotification) { + let monitor = NetworkMonitor() + func applicationDidFinishLaunching(aNotification: NSNotification) { + let nc = NSNotificationCenter.defaultCenter() + nc.addObserver(self, selector: #selector(onNetworkListUpdated(_:)), name: networkUpdateKey, object: nil) statusItem.image = NSImage(named: "MenuBarIconMac") @@ -50,6 +53,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillTerminate(aNotification: NSNotification) { // Insert code here to tear down your application + let nc = NSNotificationCenter.defaultCenter() + nc.removeObserver(self) } @@ -89,5 +94,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { func quit() { NSApp.performSelector(#selector(NSApp.terminate(_:)), withObject: nil, afterDelay: 0.0) } + + func onNetworkListUpdated(note: NSNotification) { + let netList = note.userInfo!["networks"] as! [Network] + (networkListPopover.contentViewController as! ShowNetworksViewController).setNetworks(netList) + } } diff --git a/ZeroTier One/Info.plist b/ZeroTier One/Info.plist index 5777ef6c6..29e935d0d 100644 --- a/ZeroTier One/Info.plist +++ b/ZeroTier One/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 2 + 3 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) LSUIElement diff --git a/ZeroTier One/NetworkMonitor.swift b/ZeroTier One/NetworkMonitor.swift new file mode 100644 index 000000000..124fce265 --- /dev/null +++ b/ZeroTier One/NetworkMonitor.swift @@ -0,0 +1,116 @@ +// +// NetworkMonitor.swift +// ZeroTier One +// +// Created by Grant Limberg on 6/16/16. +// Copyright © 2016 ZeroTier, Inc. All rights reserved. +// + +import Cocoa + +let networkUpdateKey = "com.zerotier.one.network-list" + +class NetworkMonitor: NSObject { + + var timer: NSTimer? = nil + + var savedNetworks: [Network] = [Network]() + var receivedNetworks: [Network] = [Network]() + var allNetworks: [Network] = [Network]() + + override init() { + super.init() + + timer = NSTimer.scheduledTimerWithTimeInterval(1.0, + target: self, + selector: #selector(updateNetworkInfo), + userInfo: nil, + repeats: true) + } + + deinit { + timer?.invalidate() + } + + private func dataFile() -> String { + var appSupport = NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask)[0] + appSupport = appSupport.URLByAppendingPathComponent("ZeroTier").URLByAppendingPathComponent("One").URLByAppendingPathComponent("networks.dat") + return appSupport.path! + } + + func updateNetworkInfo() { + let filePath = dataFile() + + if NSFileManager.defaultManager().fileExistsAtPath(filePath) { + self.savedNetworks = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Network] + + } + + ServiceCom.getNetworkList() { (networkList) -> Void in + self.receivedNetworks = networkList + + NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in + self.internal_updateNetworkInfo() + } + } + } + + func deleteSavedNetwork(nwid: String) { + if let nwid = UInt64(nwid, radix: 16) { + let index = findNetworkWithID(nwid) + + if index != NSNotFound { + allNetworks.removeAtIndex(index) + } + } + } + + // Only to be called by updateNetworkInfo() + private func internal_updateNetworkInfo() { + var networks = self.savedNetworks + + for nw in receivedNetworks { + let index = findNetworkWithID(nw.nwid) + + if index != NSNotFound { + networks[index] = nw + } + networks.sortInPlace({ (left, right) -> Bool in + if left.nwid < right.nwid { + return true + } + + return false + }) + + objc_sync_enter(allNetworks) + allNetworks = networks + objc_sync_exit(allNetworks) + + saveNetworks() + + let nc = NSNotificationCenter.defaultCenter() + + nc.postNotificationName(networkUpdateKey, object: nil, userInfo: ["networks": networks]) + } + } + + private func findNetworkWithID(nwid: UInt64) -> Int { + for (index, element) in allNetworks.enumerate() { + + if element.nwid == nwid { + return index + } + } + + return NSNotFound + } + + private func saveNetworks() { + let file = dataFile() + + objc_sync_enter(allNetworks) + NSKeyedArchiver.archiveRootObject(self.allNetworks, toFile: file) + objc_sync_exit(allNetworks) + } +} diff --git a/ZeroTier One/ServiceCom.swift b/ZeroTier One/ServiceCom.swift index e25266105..21d5529c6 100644 --- a/ZeroTier One/ServiceCom.swift +++ b/ZeroTier One/ServiceCom.swift @@ -87,6 +87,11 @@ class ServiceCom: NSObject { let request = NSMutableURLRequest(URL: u) let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(request) { (data, response, error) in + if error != nil{ + NSLog("\(error)") + return + } + let httpResponse = response as! NSHTTPURLResponse let status = httpResponse.statusCode diff --git a/ZeroTier One/ShowNetworksViewController.swift b/ZeroTier One/ShowNetworksViewController.swift index d9a4291a0..e8b9e332e 100644 --- a/ZeroTier One/ShowNetworksViewController.swift +++ b/ZeroTier One/ShowNetworksViewController.swift @@ -10,20 +10,18 @@ import Cocoa class ShowNetworksViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource { - @IBOutlet var tableView: NSTableView! + @IBOutlet var tableView: NSTableView? var networkList: [Network] = [Network]() - - - var timer: NSTimer? = nil + var netMonitor: NetworkMonitor! override func viewDidLoad() { super.viewDidLoad() // Do view setup here. - tableView.setDelegate(self) - tableView.setDataSource(self) - tableView.backgroundColor = NSColor.clearColor() + tableView?.setDelegate(self) + tableView?.setDataSource(self) + tableView?.backgroundColor = NSColor.clearColor() } private func dataFile() -> String { @@ -32,94 +30,25 @@ class ShowNetworksViewController: NSViewController, NSTableViewDelegate, NSTable return appSupport.path! } - - private func findNetworkWithID(id: UInt64) -> Int { - - for (index, element) in networkList.enumerate() { - - if element.nwid == id { - return index - } - } - - return NSNotFound - } - override func viewWillAppear() { super.viewWillAppear() - - updateNetworkInfo() - - self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(updateNetworkInfo), userInfo: nil, repeats: true) } override func viewWillDisappear() { super.viewWillDisappear() - self.timer?.invalidate() - let filePath = dataFile() NSKeyedArchiver.archiveRootObject(self.networkList, toFile: filePath) } func deleteNetworkFromList(nwid: String) { - if let nwid = UInt64(nwid, radix: 16) { - let index = findNetworkWithID(nwid) - if index != NSNotFound { - networkList.removeAtIndex(index) - tableView.reloadData() - } - } } - func updateNetworkInfo() { - let filePath = self.dataFile() - if NSFileManager.defaultManager().fileExistsAtPath(filePath) { - self.networkList = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Network] - - ServiceCom.getNetworkList() { (networkList) -> Void in - - for nw in networkList { - let index = self.findNetworkWithID(nw.nwid) - - if index != NSNotFound { - self.networkList[index] = nw - } - else { - self.networkList.append(nw) - } - } - - NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in - self.networkList.sortInPlace({ (left, right) -> Bool in - if left.nwid < right.nwid { - return true - } - - return false - }) - self.tableView.reloadData() - } - } - } - else { - ServiceCom.getNetworkList() { (networkList) -> Void in - NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in - self.networkList.sortInPlace({ (left, right) -> Bool in - if left.nwid < right.nwid { - return true - } - - return false - }) - - self.networkList = networkList - self.tableView.reloadData() - } - } - } + func setNetworks(list: [Network]) { + networkList = list + tableView?.reloadData() } // NSTableViewDataSource