ZeroTierOne/ZeroTier One/NetworkMonitor.swift
Grant Limberg a156fec25a put node ID into the main menu.
Clicking on the menu item copies the node ID into the clipboard.
2016-06-30 21:24:45 -07:00

154 lines
4.2 KiB
Swift

//
// 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"
let statusUpdateKey = "com.zerotier.one.status"
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) {
let networks = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Network]
self.savedNetworks.removeAll()
for n in networks {
self.savedNetworks.append(n)
}
}
ServiceCom.getNetworkList() { (networkList) -> Void in
self.receivedNetworks = networkList
NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in
self.internal_updateNetworkInfo()
}
}
ServiceCom.getNodeStatus() { nodeStatus -> Void in
NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in
let nc = NSNotificationCenter.defaultCenter()
nc.postNotificationName(statusUpdateKey, object: nil, userInfo: ["status": nodeStatus])
}
}
}
func deleteSavedNetwork(nwid: String) {
if let nwid = UInt64(nwid, radix: 16) {
let index = findNetworkWithID(nwid)
if index != NSNotFound {
allNetworks.removeAtIndex(index)
}
let index2 = findSavedNetworkWithID(nwid)
if index2 != NSNotFound {
savedNetworks.removeAtIndex(index2)
}
}
saveNetworks()
}
// Only to be called by updateNetworkInfo()
private func internal_updateNetworkInfo() {
var networks = self.savedNetworks
for nw in receivedNetworks {
let index = findSavedNetworkWithID(nw.nwid)
if index != NSNotFound {
networks[index] = nw
}
else {
networks.append(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 findSavedNetworkWithID(nwid: UInt64) -> Int {
for (index, element) in savedNetworks.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)
}
}