Last active
August 29, 2015 14:25
-
-
Save traviskirton/41d9647f4377ada3921b to your computer and use it in GitHub Desktop.
PeripheralSocketManager class, from the HouseKeeping chapter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AppDelegate.swift | |
// MOPeripheral | |
// | |
// Created by travis on 2015-07-17. | |
// Copyright (c) 2015 C4. All rights reserved. | |
// | |
import UIKit | |
@UIApplicationMain | |
public class AppDelegate: UIResponder, UIApplicationDelegate { | |
//default iOS, needs to be here | |
public var window: UIWindow? | |
public var socketManager = PeripheralSocketManager() | |
public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { | |
socketManager.startSearching() | |
return true | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PeripheralSocketManager.swift | |
// MOPeripheral | |
// | |
// Created by travis on 2015-07-22. | |
// Copyright (c) 2015 C4. All rights reserved. | |
// | |
import Foundation | |
import C4 | |
public class PeripheralSocketManager : NSObject, NSNetServiceBrowserDelegate, NSNetServiceDelegate, GCDAsyncSocketDelegate { | |
//the browser will look for the core | |
public var netServiceBrowser : NSNetServiceBrowser? | |
//a variable to store a local version of the core's service | |
var coreService : NSNetService? | |
//a list of addresses that point to a broadcast NSNetService | |
var serverAddresses : [NSData]? | |
//the socket that will be used to connect to the core app | |
var localSocket : GCDAsyncSocket? | |
var coreSocket : GCDAsyncSocket? | |
public override init() { | |
super.init() | |
//create the browser, it will look for the core | |
netServiceBrowser = NSNetServiceBrowser() | |
//set its delegate | |
netServiceBrowser?.delegate = self | |
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handle:", name: "tap", object: nil) | |
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handle:", name: "longpress", object: nil) | |
} | |
public func startSearching() { | |
//start searching for services | |
netServiceBrowser?.searchForServicesOfType("_m-o._tcp.", inDomain: "local.") | |
} | |
public func stopSearching() { | |
//start searching for services | |
netServiceBrowser?.stop() | |
} | |
//MARK: NetServiceBrowser Delegate Methods | |
public func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) { | |
println(__FUNCTION__) | |
} | |
public func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didFindService aNetService: NSNetService, moreComing: Bool) { | |
println(__FUNCTION__) | |
if coreService != nil { | |
coreService?.stop() | |
coreService?.delegate = nil | |
} | |
coreService = aNetService; | |
coreService?.delegate = self | |
coreService?.resolveWithTimeout(5.0) | |
} | |
public func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didNotSearch errorDict: [NSObject : AnyObject]) { | |
println("\(__FUNCTION__) error: \(errorDict)") | |
} | |
public func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didRemoveDomain domainString: String, moreComing: Bool) { | |
println(__FUNCTION__) | |
} | |
public func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didRemoveService aNetService: NSNetService, moreComing: Bool) { | |
println(__FUNCTION__) | |
} | |
public func netServiceBrowserDidStopSearch(aNetServiceBrowser: NSNetServiceBrowser) { | |
println(__FUNCTION__) | |
} | |
public func netServiceBrowserWillSearch(aNetServiceBrowser: NSNetServiceBrowser) { | |
println(__FUNCTION__) | |
} | |
public func netServiceDidResolveAddress(sender: NSNetService) { | |
println(__FUNCTION__) | |
//if there are any addresses left over from a previous connection | |
if serverAddresses != nil { | |
//remove them | |
serverAddresses?.removeAll(keepCapacity: false) | |
} else { | |
//otherwise, create a new array to hold incoming addresses | |
serverAddresses = [NSData]() | |
} | |
//if the net service that was found has addresses | |
if let count = sender.addresses?.count, | |
//and the addresses are not nil (i.e. we can extract them) | |
let addresses = sender.addresses as? [NSData] { | |
//then cycle through all the addresses and append them to the local array | |
for i in 0..<count { | |
serverAddresses?.append(addresses[i]) | |
} | |
} | |
//create a new socket if it hasn't yet been created | |
if (localSocket == nil) { | |
localSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue()) | |
} | |
connectToNextAddress() | |
} | |
public func netService(sender: NSNetService, didNotResolve errorDict: [NSObject : AnyObject]) { | |
println(__FUNCTION__) | |
} | |
public func connectToNextAddress() { | |
println(__FUNCTION__) | |
//variable representing the socket's attempt to connect to an address | |
var done = false | |
//loop through all the addresses until we either run out, or have connected to one of them | |
while !done && serverAddresses?.count > 0 { | |
//grab the first address | |
var address = serverAddresses?[0] | |
//remove it from the list | |
serverAddresses?.removeAtIndex(0) | |
//try connecting to the first address | |
var error : NSError? | |
if let response = localSocket?.connectToAddress(address , error: &error) { | |
//if the socket connects, mark done | |
done = response | |
} | |
} | |
} | |
//MARK: GCDAsyncSocket Delegate Methods | |
public func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) { | |
println(__FUNCTION__) | |
coreSocket = sock | |
writeTo(coreSocket!, message: "handshake-from-peripheral") | |
} | |
public func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) { | |
//extracts the data, converts it to a string | |
if let message = NSString(data: data, encoding: NSUTF8StringEncoding) { | |
println("\(__FUNCTION__) message: \(message)") | |
} | |
coreSocket?.readDataWithTimeout(-1, tag: 0) | |
} | |
public func socket(sock: GCDAsyncSocket!, didWriteDataWithTag tag: Int) { | |
println(__FUNCTION__) | |
} | |
//MARK: Custom | |
func writeTo(sock: GCDAsyncSocket, message: String) { | |
println(__FUNCTION__) | |
//converts the message to data | |
let data = NSMutableData(data: message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!) | |
//appends an extra bit of data that acts as an "end point" for reading | |
data.appendData(GCDAsyncSocket.CRLFData()) | |
//writes the full data to the socket | |
sock.writeData(data, withTimeout: -1, tag: 0) | |
//tells the socket to read until it reaches the "end point" | |
sock.readDataToData(GCDAsyncSocket.CRLFData(), withTimeout: -1, tag: 0) | |
} | |
func handle(notification: NSNotification) { | |
//checks to see if the notification is down or dragged | |
if notification.name == "tap" || notification.name == "longpress" { | |
//if so, attempt to convert the notification's userInfo into a dictionary with the right types | |
if let info = notification.userInfo as? Dictionary<String,String> { | |
//check to see if the "event" actually exists | |
if let location = info["location"], | |
let state = info["state"] { | |
relayGesture("\(notification.name)|\(location)|\(state.toInt())|") | |
} | |
else { | |
println("no value for 'event'") | |
} | |
} else { | |
println("wrong userInfo type") | |
} | |
} | |
} | |
func relayGesture(message: String) { | |
if let sock = coreSocket { | |
writeTo(sock, message: message) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment