Server code to fetch and toggle devices
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
0C63A8851C33DC29007E4B52 /* VerticalBlur.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 0C63A8831C33DC29007E4B52 /* VerticalBlur.vsh */; };
|
||||
0C63A8881C33EB3B007E4B52 /* FinalRender.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 0C63A8861C33EB3B007E4B52 /* FinalRender.fsh */; };
|
||||
0C63A8891C33EB3B007E4B52 /* FinalRender.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 0C63A8871C33EB3B007E4B52 /* FinalRender.vsh */; };
|
||||
0CAA32791C361A2400B353CF /* WemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CAA32781C361A2400B353CF /* WemoServer.swift */; };
|
||||
0CAA327B1C361CBE00B353CF /* NSErrorAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CAA327A1C361CBE00B353CF /* NSErrorAdditions.swift */; };
|
||||
0CAA327D1C361ECA00B353CF /* StandardError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CAA327C1C361ECA00B353CF /* StandardError.swift */; };
|
||||
0CF0F8961C362D8F00FE7752 /* NSURLAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0F8951C362D8F00FE7752 /* NSURLAdditions.swift */; };
|
||||
0CF9A48E1C35E9C800276F13 /* SwitchIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF9A48D1C35E9C800276F13 /* SwitchIndicatorView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -62,6 +66,10 @@
|
||||
0C63A8831C33DC29007E4B52 /* VerticalBlur.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = VerticalBlur.vsh; sourceTree = "<group>"; };
|
||||
0C63A8861C33EB3B007E4B52 /* FinalRender.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = FinalRender.fsh; sourceTree = "<group>"; };
|
||||
0C63A8871C33EB3B007E4B52 /* FinalRender.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = FinalRender.vsh; sourceTree = "<group>"; };
|
||||
0CAA32781C361A2400B353CF /* WemoServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WemoServer.swift; sourceTree = "<group>"; };
|
||||
0CAA327A1C361CBE00B353CF /* NSErrorAdditions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSErrorAdditions.swift; sourceTree = "<group>"; };
|
||||
0CAA327C1C361ECA00B353CF /* StandardError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StandardError.swift; sourceTree = "<group>"; };
|
||||
0CF0F8951C362D8F00FE7752 /* NSURLAdditions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSURLAdditions.swift; sourceTree = "<group>"; };
|
||||
0CF9A48D1C35E9C800276F13 /* SwitchIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchIndicatorView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -102,6 +110,7 @@
|
||||
0C41EF491C34B51500AF847F /* SwitchesViewController.swift */,
|
||||
0C20E2BA1C33529700BA789B /* MainViewController.swift */,
|
||||
0C20E2BC1C33534F00BA789B /* VisualizationViewController.swift */,
|
||||
0CAA32781C361A2400B353CF /* WemoServer.swift */,
|
||||
);
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
@@ -194,6 +203,9 @@
|
||||
0C63A8791C33C622007E4B52 /* Utilities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CAA327C1C361ECA00B353CF /* StandardError.swift */,
|
||||
0CAA327A1C361CBE00B353CF /* NSErrorAdditions.swift */,
|
||||
0CF0F8951C362D8F00FE7752 /* NSURLAdditions.swift */,
|
||||
0C63A87B1C33C655007E4B52 /* NSValue+XIONAdditions.h */,
|
||||
0C63A87C1C33C655007E4B52 /* NSValue+XIONAdditions.m */,
|
||||
);
|
||||
@@ -282,6 +294,9 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0C41EF4E1C34B81F00AF847F /* KSIRingView.m in Sources */,
|
||||
0CAA327B1C361CBE00B353CF /* NSErrorAdditions.swift in Sources */,
|
||||
0CF0F8961C362D8F00FE7752 /* NSURLAdditions.swift in Sources */,
|
||||
0CAA32791C361A2400B353CF /* WemoServer.swift in Sources */,
|
||||
0C41EF561C35ABCD00AF847F /* ConnectionStatusView.swift in Sources */,
|
||||
0C63A87D1C33C655007E4B52 /* NSValue+XIONAdditions.m in Sources */,
|
||||
0C20E2BD1C33534F00BA789B /* VisualizationViewController.swift in Sources */,
|
||||
@@ -291,6 +306,7 @@
|
||||
0C41EF501C34B97700AF847F /* HeaderView.swift in Sources */,
|
||||
0C41EF541C34BC9800AF847F /* XIONLogoView.swift in Sources */,
|
||||
0C4315061C35E67600164559 /* WemoCellView.swift in Sources */,
|
||||
0CAA327D1C361ECA00B353CF /* StandardError.swift in Sources */,
|
||||
0CF9A48E1C35E9C800276F13 /* SwitchIndicatorView.swift in Sources */,
|
||||
0C4315001C35B1E700164559 /* WemoDevice.swift in Sources */,
|
||||
);
|
||||
|
||||
@@ -9,10 +9,24 @@
|
||||
import UIKit
|
||||
|
||||
class MainViewController: UIViewController, SwitchesViewControllerDelegate {
|
||||
private var _server: WemoServer
|
||||
private var _visualizationController: VisualizationViewController = VisualizationViewController()
|
||||
private var _switchesController: SwitchesViewController = SwitchesViewController()
|
||||
private var _headerView: HeaderView = HeaderView()
|
||||
|
||||
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
|
||||
{
|
||||
let url = NSURL(string: "http://10.0.1.4:8000")
|
||||
_server = WemoServer(url!)
|
||||
|
||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
fatalError("unsupported")
|
||||
}
|
||||
|
||||
// MARK: Overrides
|
||||
|
||||
override func viewDidLoad()
|
||||
@@ -30,12 +44,7 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
|
||||
|
||||
self.view.addSubview(_headerView)
|
||||
|
||||
// DEBUG
|
||||
for _ in 0 ..< 10 {
|
||||
let device = WemoDevice()
|
||||
device.name = "beatmania IIDX"
|
||||
self.devices.append(device)
|
||||
}
|
||||
_updateConnectivityStatus(.Disconnected)
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews()
|
||||
@@ -78,6 +87,15 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
|
||||
override func viewDidAppear(animated: Bool)
|
||||
{
|
||||
_headerView.xionLogoView.beginAnimating()
|
||||
|
||||
_updateConnectivityStatus(.Connecting)
|
||||
_server.connect { (error: NSError?) -> Void in
|
||||
if (error == nil) {
|
||||
self._reloadDevices()
|
||||
} else {
|
||||
self._updateConnectivityStatus(.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidDisappear(animated: Bool)
|
||||
@@ -106,6 +124,10 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
|
||||
func switchesViewControllerDidToggleDevices(controller: SwitchesViewController, devices: [WemoDevice])
|
||||
{
|
||||
_updateVisualization(true)
|
||||
|
||||
for device in devices {
|
||||
_server.toggleDevice(device, state: device.state, completion: { (error: NSError?) -> Void in })
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Internal
|
||||
@@ -124,4 +146,26 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
|
||||
_visualizationController.setPercentActivated(percentageActivated, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
internal func _updateConnectivityStatus(status: ConnectionStatus)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue()) { () -> Void in
|
||||
self._headerView.connectionStatusView.connectivityStatus = status
|
||||
}
|
||||
}
|
||||
|
||||
internal func _reloadDevices()
|
||||
{
|
||||
_server.fetchDevices({ (devices: [WemoDevice], error: NSError?) -> Void in
|
||||
dispatch_async(dispatch_get_main_queue()) { () -> Void in
|
||||
if (error == nil) {
|
||||
self.devices = devices
|
||||
self._updateConnectivityStatus(.Connected)
|
||||
} else {
|
||||
self.devices = []
|
||||
self._updateConnectivityStatus(.Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ class SwitchesViewController: UIViewController,
|
||||
_collectionView.registerClass(WemoDeviceCellView.self, forCellWithReuseIdentifier: deviceCellReuseID)
|
||||
_collectionView.registerClass(WemoActionCellView.self, forCellWithReuseIdentifier: actionCellReuseID)
|
||||
self.view.addSubview(_collectionView)
|
||||
|
||||
self.devices = []
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews()
|
||||
@@ -102,6 +104,7 @@ class SwitchesViewController: UIViewController,
|
||||
let reuseID = SwitchesViewController.collectionViewActionCellReuseIdentifier
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseID, forIndexPath: indexPath) as! WemoActionCellView
|
||||
cell.textLabel.text = ActionCell(rawValue: indexPath.item)?.name().uppercaseString
|
||||
cell.enabled = (self.devices.count > 0)
|
||||
|
||||
return cell
|
||||
} else {
|
||||
@@ -136,8 +139,8 @@ class SwitchesViewController: UIViewController,
|
||||
{
|
||||
if (indexPath.item < ActionCell.count) {
|
||||
let tappedActionCell = ActionCell(rawValue: indexPath.item)
|
||||
|
||||
var currentDelay: NSTimeInterval = 0.0
|
||||
|
||||
for var i = ActionCell.count; i < collectionView.numberOfItemsInSection(indexPath.section); ++i {
|
||||
let cell = collectionView.cellForItemAtIndexPath(NSIndexPath(forItem: i, inSection: indexPath.section)) as! WemoDeviceCellView
|
||||
|
||||
@@ -164,4 +167,22 @@ class SwitchesViewController: UIViewController,
|
||||
self.delegate?.switchesViewControllerDidToggleDevices(self, devices: [device])
|
||||
}
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool
|
||||
{
|
||||
if (indexPath.item < ActionCell.count) {
|
||||
return (self.devices.count > 0)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool
|
||||
{
|
||||
if (indexPath.item < ActionCell.count) {
|
||||
return (self.devices.count > 0)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
134
XIONControlPanel/Controllers/WemoServer.swift
Normal file
134
XIONControlPanel/Controllers/WemoServer.swift
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// WemoServer.swift
|
||||
// XIONControlPanel
|
||||
//
|
||||
// Created by Charles Magahern on 12/31/15.
|
||||
// Copyright © 2015 XION. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ConnectionStatus {
|
||||
case Disconnected
|
||||
case Connecting
|
||||
case Connected
|
||||
case Error
|
||||
}
|
||||
|
||||
class WemoServer {
|
||||
private(set) var baseURL: NSURL
|
||||
private(set) var connected: Bool = false
|
||||
|
||||
private var _urlSession: NSURLSession
|
||||
private var _errorStream: StandardErrorOutputStream = StandardErrorOutputStream()
|
||||
|
||||
init(_ url: NSURL)
|
||||
{
|
||||
self.baseURL = url
|
||||
|
||||
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
|
||||
_urlSession = NSURLSession(configuration: config)
|
||||
}
|
||||
|
||||
func connect(completion: (NSError?) -> Void)
|
||||
{
|
||||
if (!self.connected) {
|
||||
let url = self.baseURL.URLByAppendingPathComponent("api/environment")
|
||||
let request = NSMutableURLRequest(URL: url)
|
||||
request.HTTPMethod = "POST"
|
||||
|
||||
let task = _urlSession.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
|
||||
var clientError: NSError? = nil
|
||||
|
||||
if (error != nil) {
|
||||
clientError = NSError.xionError(.ConnectionError, underlying: error!)
|
||||
self._logError("Error connecting to server", error: clientError!)
|
||||
} else {
|
||||
self.connected = true
|
||||
}
|
||||
|
||||
completion(clientError)
|
||||
}
|
||||
task.resume()
|
||||
} else {
|
||||
completion(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func disconnect(completion: (NSError?) -> Void)
|
||||
{
|
||||
self.connected = false
|
||||
completion(nil)
|
||||
}
|
||||
|
||||
func fetchDevices(completion: ([WemoDevice], NSError?) -> Void)
|
||||
{
|
||||
if (self.connected) {
|
||||
let url = self.baseURL.URLByAppendingPathComponent("api/environment")
|
||||
let task = _urlSession.dataTaskWithURL(url) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
|
||||
var devices: [WemoDevice] = []
|
||||
var clientError: NSError? = nil
|
||||
|
||||
if (data != nil) {
|
||||
devices = self._parseDevices(data!)
|
||||
} else {
|
||||
clientError = NSError.xionError(.ConnectionError, underlying: error)
|
||||
self._logError("Error fetching devices", error: clientError!)
|
||||
}
|
||||
|
||||
completion(devices, clientError)
|
||||
}
|
||||
task.resume()
|
||||
} else {
|
||||
let err = NSError.xionError(.ConnectionError)
|
||||
completion([], err)
|
||||
}
|
||||
}
|
||||
|
||||
func toggleDevice(device: WemoDevice, state: WemoDevice.State, completion: (NSError?) -> Void)
|
||||
{
|
||||
if (self.connected) {
|
||||
let stateArg = (state == .On ? "on" : "off")
|
||||
let url = self.baseURL.URLByAppendingPathComponent("api/device/\(device.name)").URLByAppendingRequestParameters(["state" : stateArg])
|
||||
let request = NSMutableURLRequest(URL: url!)
|
||||
request.HTTPMethod = "POST"
|
||||
|
||||
let task = _urlSession.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
|
||||
var clientError: NSError? = nil
|
||||
|
||||
if (error != nil) {
|
||||
clientError = NSError.xionError(.ConnectionError, underlying: error)
|
||||
}
|
||||
|
||||
completion(clientError)
|
||||
}
|
||||
task.resume()
|
||||
} else {
|
||||
let err = NSError.xionError(.ConnectionError)
|
||||
completion(err)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal func _logError(description: String, error: NSError)
|
||||
{
|
||||
print("ERROR: \(description) \(error)", toStream: &_errorStream)
|
||||
}
|
||||
|
||||
internal func _parseDevices(data: NSData) -> [WemoDevice]
|
||||
{
|
||||
var devices: [WemoDevice] = []
|
||||
|
||||
if let responseDict = (try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as? NSDictionary) {
|
||||
for responseObj in (responseDict?.allValues)! {
|
||||
if let responseDict = responseObj as? NSDictionary {
|
||||
let device = WemoDevice(responseDict)
|
||||
devices.append(device)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return devices
|
||||
}
|
||||
}
|
||||
@@ -28,35 +28,33 @@ class WemoDevice {
|
||||
init()
|
||||
{}
|
||||
|
||||
init(_ responseData: NSData)
|
||||
init(_ dict: NSDictionary)
|
||||
{
|
||||
if let dict = (try? NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions())) as? NSDictionary {
|
||||
if let name = dict["name"] as? NSString {
|
||||
self.name = String(name)
|
||||
}
|
||||
|
||||
if let host = dict["host"] as? NSString {
|
||||
self.host = String(host)
|
||||
}
|
||||
|
||||
if let model = dict["model"] as? NSString {
|
||||
self.model = String(model)
|
||||
}
|
||||
|
||||
if let state = dict["state"] as? NSNumber {
|
||||
switch (state.integerValue) {
|
||||
case 0:
|
||||
self.state = .Off
|
||||
case 1:
|
||||
self.state = .On
|
||||
default:
|
||||
self.state = .Off
|
||||
}
|
||||
}
|
||||
|
||||
if let serial = dict["serialnumber"] as? NSString {
|
||||
self.serial = String(serial)
|
||||
if let name = dict["name"] as? NSString {
|
||||
self.name = String(name)
|
||||
}
|
||||
|
||||
if let host = dict["host"] as? NSString {
|
||||
self.host = String(host)
|
||||
}
|
||||
|
||||
if let model = dict["model"] as? NSString {
|
||||
self.model = String(model)
|
||||
}
|
||||
|
||||
if let state = dict["state"] as? NSNumber {
|
||||
switch (state.integerValue) {
|
||||
case 0:
|
||||
self.state = .Off
|
||||
case 1:
|
||||
self.state = .On
|
||||
default:
|
||||
self.state = .Off
|
||||
}
|
||||
}
|
||||
|
||||
if let serial = dict["serialnumber"] as? NSString {
|
||||
self.serial = String(serial)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Orbitron-Medium.ttf</string>
|
||||
|
||||
45
XIONControlPanel/Utilities/NSErrorAdditions.swift
Normal file
45
XIONControlPanel/Utilities/NSErrorAdditions.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// NSErrorAdditions.swift
|
||||
// XIONControlPanel
|
||||
//
|
||||
// Created by Charles Magahern on 12/31/15.
|
||||
// Copyright © 2015 XION. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum XIONErrorCode: Int {
|
||||
case Unknown
|
||||
case ConnectionError
|
||||
}
|
||||
|
||||
extension NSError {
|
||||
private static let XIONErrorDomain = "com.xionsf.controlpanel"
|
||||
|
||||
class func xionError(code: XIONErrorCode) -> NSError
|
||||
{
|
||||
return self.xionError(code, userInfo: nil)
|
||||
}
|
||||
|
||||
class func xionError(code: XIONErrorCode, underlying: NSError?) -> NSError
|
||||
{
|
||||
var userInfo: [NSObject : AnyObject]? = nil
|
||||
if (underlying != nil) {
|
||||
userInfo = [
|
||||
NSUnderlyingErrorKey : underlying!
|
||||
]
|
||||
}
|
||||
|
||||
return self.xionError(code, userInfo: userInfo)
|
||||
}
|
||||
|
||||
class func xionError(code: XIONErrorCode, userInfo: [NSObject : AnyObject]?) -> NSError
|
||||
{
|
||||
return NSError(domain: XIONErrorDomain, code: code.rawValue, userInfo: userInfo)
|
||||
}
|
||||
|
||||
var xionErrorCode: XIONErrorCode
|
||||
{
|
||||
return XIONErrorCode(rawValue: self.code)!
|
||||
}
|
||||
}
|
||||
54
XIONControlPanel/Utilities/NSURLAdditions.swift
Normal file
54
XIONControlPanel/Utilities/NSURLAdditions.swift
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// NSURLAdditions.swift
|
||||
// ArchillectTV
|
||||
//
|
||||
// Created by Charles Magahern on 10/25/15.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension NSURL {
|
||||
var requestParameters: [String : String]? {
|
||||
get
|
||||
{
|
||||
let urlComponents = self.absoluteString.componentsSeparatedByString("/")
|
||||
let paramsString = urlComponents[urlComponents.count - 1]
|
||||
let parameterComponents = paramsString.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "&?"))
|
||||
var dict: Dictionary<String, String> = Dictionary()
|
||||
|
||||
for paramPair in parameterComponents {
|
||||
let kvPair = paramPair.componentsSeparatedByString("=")
|
||||
if (kvPair.count == 2 && kvPair[0].characters.count > 0) {
|
||||
let key = kvPair[0].stringByRemovingPercentEncoding!
|
||||
let value = kvPair[1].stringByRemovingPercentEncoding!
|
||||
dict[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return dict
|
||||
}
|
||||
}
|
||||
|
||||
func URLByAppendingRequestParameters(params: [String : String]) -> NSURL?
|
||||
{
|
||||
var paramsString = ""
|
||||
|
||||
for (key, value) in params {
|
||||
var delim = ""
|
||||
if (paramsString.characters.count == 0) {
|
||||
delim = "?"
|
||||
} else {
|
||||
delim = "&"
|
||||
}
|
||||
|
||||
let keyParam = key.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
|
||||
let valueParam = value.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
|
||||
paramsString += "\(delim)\(keyParam!)=\(valueParam!)"
|
||||
}
|
||||
|
||||
var absoluteString = self.absoluteString
|
||||
absoluteString += paramsString
|
||||
|
||||
return NSURL(string: absoluteString)
|
||||
}
|
||||
}
|
||||
16
XIONControlPanel/Utilities/StandardError.swift
Normal file
16
XIONControlPanel/Utilities/StandardError.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// StandardError.swift
|
||||
// XIONControlPanel
|
||||
//
|
||||
// Created by Charles Magahern on 12/31/15.
|
||||
// Copyright © 2015 XION. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class StandardErrorOutputStream: OutputStreamType {
|
||||
func write(string: String) {
|
||||
let stderr = NSFileHandle.fileHandleWithStandardError()
|
||||
stderr.writeData(string.dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
class ConnectionStatusView: UIView {
|
||||
private var _connectivityStatus:Bool = false
|
||||
private var _japaneseLabel: UILabel = UILabel()
|
||||
private var _englishLabel: UILabel = UILabel()
|
||||
private var _connectivityStatus: ConnectionStatus = .Disconnected
|
||||
private var _japaneseLabel: UILabel = UILabel()
|
||||
private var _englishLabel: UILabel = UILabel()
|
||||
|
||||
static private let labelsVMargin: CGFloat = 5.0
|
||||
|
||||
@@ -27,7 +27,7 @@ class ConnectionStatusView: UIView {
|
||||
_englishLabel.textColor = UIColor.whiteColor()
|
||||
self.addSubview(_englishLabel)
|
||||
|
||||
self.connectivityStatus = false
|
||||
self.connectivityStatus = .Disconnected
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
@@ -74,7 +74,7 @@ class ConnectionStatusView: UIView {
|
||||
|
||||
// MARK: API
|
||||
|
||||
var connectivityStatus: Bool
|
||||
var connectivityStatus: ConnectionStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -85,17 +85,30 @@ class ConnectionStatusView: UIView {
|
||||
{
|
||||
_connectivityStatus = newStatus
|
||||
|
||||
if (_connectivityStatus == true) {
|
||||
switch (_connectivityStatus) {
|
||||
case .Disconnected:
|
||||
_japaneseLabel.text = "非直結"
|
||||
_japaneseLabel.textColor = UIColor.redColor()
|
||||
|
||||
_englishLabel.text = "offline"
|
||||
_englishLabel.textColor = UIColor.redColor()
|
||||
case .Connecting:
|
||||
_japaneseLabel.text = "接続中"
|
||||
_japaneseLabel.textColor = UIColor.yellowColor()
|
||||
|
||||
_englishLabel.text = "connecting..."
|
||||
_englishLabel.textColor = UIColor.yellowColor()
|
||||
case .Connected:
|
||||
_japaneseLabel.text = "直結"
|
||||
_japaneseLabel.textColor = UIColor.greenColor()
|
||||
|
||||
_englishLabel.text = "online"
|
||||
_englishLabel.textColor = UIColor.greenColor()
|
||||
} else {
|
||||
_japaneseLabel.text = "非直結"
|
||||
case .Error:
|
||||
_japaneseLabel.text = "過失"
|
||||
_japaneseLabel.textColor = UIColor.redColor()
|
||||
|
||||
_englishLabel.text = "offline"
|
||||
_englishLabel.text = "error"
|
||||
_englishLabel.textColor = UIColor.redColor()
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ public class WemoDeviceCellView: WemoCellView {
|
||||
}
|
||||
|
||||
public class WemoActionCellView: WemoCellView {
|
||||
public var textLabel: UILabel = UILabel()
|
||||
var textLabel: UILabel = UILabel()
|
||||
|
||||
override init(frame: CGRect)
|
||||
{
|
||||
@@ -197,4 +197,16 @@ public class WemoActionCellView: WemoCellView {
|
||||
super.layoutSubviews()
|
||||
self.textLabel.frame = self.bounds
|
||||
}
|
||||
|
||||
var enabled: Bool = true
|
||||
{
|
||||
didSet
|
||||
{
|
||||
if (enabled) {
|
||||
self.textLabel.textColor = UIColor.whiteColor()
|
||||
} else {
|
||||
self.textLabel.textColor = UIColor.darkGrayColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user