Skip to content

Instantly share code, notes, and snippets.

@sirolf2009
Created November 6, 2015 15:11
Show Gist options
  • Save sirolf2009/ff7e7cd98350e510da1e to your computer and use it in GitHub Desktop.
Save sirolf2009/ff7e7cd98350e510da1e to your computer and use it in GitHub Desktop.
A rest api based socket client in swift
import Foundation
class Client : NSObject, NSStreamDelegate {
var host: String = ""
var listeners: [Listener] = [Listener]()
var ID: String = ""
var connected: Bool = false
func connect(host: String, port: Int) {
self.host = host+":"+String(port)
connect()
}
func connect() {
let request = NSMutableURLRequest()
request.URL = NSURL(string: host+"/register")
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler: { (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
if(data != nil) {
self.ID = String(NSString(data: data!, encoding: NSUTF8StringEncoding)!)
self.connected = true
print("ID: ", self.ID)
for listener in self.listeners {
listener.connected()
}
dispatch_async(dispatch_get_global_queue(0, 0)) {
while(self.connected) {
let request = NSMutableURLRequest()
request.URL = NSURL(string: self.host+"/fetch/"+self.ID)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler: { (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
let statusCode = (response as! NSHTTPURLResponse).statusCode
if(statusCode != 200) {
print("Status Code: ", statusCode)
}
if(statusCode == 400) {
print("disconnected")
self.connected = false
for listener in self.listeners {
listener.disconnected()
}
} else if(data == nil) {
print("no data received")
} else {
do {
let jsonResult: NSArray! = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
if(jsonResult != nil && jsonResult.count > 0) {
print("Received", jsonResult!)
for item in jsonResult {
let object = Parsers.parse(item as! NSDictionary)
if(object == nil) {
print("error, could not parse")
} else if((object as? Message) != nil) {
print("message from server: ",(object as? Message)?.message)
} else {
for listener in self.listeners {
print("Notifiying listener")
listener.received(object!)
}
}
}
} else if(jsonResult == nil) {
print("could not parse to json")
}
} catch {
print("an error occured")
}
}
})
sleep(5)
}
}
} else {
print("server down?")
}
})
}
func close() {
connected = false
let request = NSMutableURLRequest()
request.URL = NSURL(string: host+"/unregister/"+self.ID)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler: { (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
})
}
func addListener(listener: Listener) {
listeners.append(listener)
}
func sendTCP(object: AnyObject) {
if(!connected) {
while(!connected) {
sleep(1)
}
}
print("Sending", object)
let request = NSMutableURLRequest()
request.URL = NSURL(string: host+"/push/"+String(ID))
request.HTTPMethod = "POST"
if((object as? DictonaryTranslatable) != nil) {
do {
try request.HTTPBody = NSJSONSerialization.dataWithJSONObject((object as! DictonaryTranslatable).toDictionary(), options: NSJSONWritingOptions(rawValue: 0))
} catch {}
}
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler: { (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
if(error != nil) {
print("error during sending ", object, " ", error)
}
})
}
}
protocol Parser {
typealias ReturnType
func parse(dict: NSDictionary) throws -> ReturnType
}
class Parsers {
class func parse(dict: NSDictionary) -> AnyObject? {
print("parsing ", dict)
//TODO add your parsers here
do {
let object = try MessageParser().parse(dict)
return object
} catch { }
return nil
}
}
class MessageParser: Parser {
typealias ReturnType = Message
func parse(dict: NSDictionary) throws -> ReturnType {
if(Checker().check(dict, variables: ["message"])) {
let object: Message = Message()
object.message = dict["message"] as! String
return object
}
throw ParseException()
}
}
class Checker {
func check(dict: NSDictionary, variables: [String]) -> Bool {
if(dict.count != variables.count) {
return false
}
for variable in variables {
if(dict[variable] == nil) {
return false
}
}
return true
}
}
class ParseException: ErrorType {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment