This tutorial from Ray Wenderlich.com http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server has a good description of the client side needed to connect to a basic server socket. It does not do any of the handshaking, heartbeat and framing required in the websocket protocol, so it is not compatible with websockets. Your code doesn't show any of the handshaking required by the websocket protocol, so I assume that's what you want. If you need websockets, take a look at https://github.com/daltoniam/Starscream
Here are the basics of my Swift interpretation. I ended up with a Manager and a Connection:
class Manager : NSObject {
var conn = Connection()
func connect() {
let (host, port) = screen.getAddress()
conn.connect(host, port: port)
}
func disconnect() {
conn.disconnect()
}
func sendMessage(params:[String : AnyObject]) {
let msg = "send_message:" + JSONStringify(params)
let data : NSData = msg.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
var buffer = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&buffer)
conn.outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
}
func JSONStringify(value: AnyObject) -> String {
if NSJSONSerialization.isValidJSONObject(value) {
if let data = NSJSONSerialization.dataWithJSONObject(value, options: nil, error: nil) {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
return string
}
}
}
return ""
}
}
class Connection : NSObject, NSStreamDelegate {
var serverAddress: CFString = "127.0.0.1"
var serverPort: UInt32 = 8443
private var inputStream: NSInputStream!
private var outputStream: NSOutputStream!
func connect(address: CFString, port:UInt32) {
println("connecting...")
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(nil, address, port, &readStream, &writeStream)
// Documentation suggests readStream and writeStream can be assumed to
// be non-nil. It might be wise to test if either is nil
// and implement error-handling as needed.
self.inputStream = readStream!.takeRetainedValue()
self.outputStream = writeStream!.takeRetainedValue()
self.inputStream.delegate = self
self.outputStream.delegate = self
self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.inputStream.open()
self.outputStream.open()
}
func disconnect() {
self.inputStream.close()
self.outputStream.close()
}
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
switch (eventCode){
case NSStreamEvent.ErrorOccurred:
NSLog("ErrorOccurred")
case NSStreamEvent.EndEncountered:
NSLog("EndEncountered")
case NSStreamEvent.None:
NSLog("None")
case NSStreamEvent.HasBytesAvailable:
NSLog("HasBytesAvaible")
var buffer = [UInt8](count: 4096, repeatedValue: 0)
while (inputStream.hasBytesAvailable){
var len = inputStream.read(&buffer, maxLength: buffer.count)
if(len > 0){
var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)
if (output != ""){
NSLog("server said: %@", output!)
}
} else {
println("empty string from stream")
}
}
case NSStreamEvent.allZeros:
NSLog("allZeros")
case NSStreamEvent.OpenCompleted:
NSLog("OpenCompleted")
case NSStreamEvent.HasSpaceAvailable:
NSLog("HasSpaceAvailable")
default: println("default reached. unknown stream event")
}
}
}
You might also find these links useful for messaging in Swift:
I'm not sure the JSON conversion in this code is working correctly. I discovered that I needed websockets, so this is no longer used.