A Swift client for SignalR. Supports hubs and persistent connections.
It's a wrapper around the SignalR JavaScript client running in a hidden web view. As such, it's subject to the same limitations of that client -- namely, no support for custom headers when using WebSockets. This is because the browser's WebSocket client does not support custom headers.
Either, your choice. Note that since WKWebView runs in a separate process, it does not have access to cookies in NSHTTPCookieStorage. If you need cookies, use UIWebView. SwiftR uses UIWebView by default, but you can choose WKWebView instead:
SwiftR.useWKWebView = true
use_frameworks!
pod 'SwiftR'
github 'adamhartford/SwiftR'
See https://github.com/adamhartford/SignalRDemo for a sample self-hosted SignalR application.
// Server
public class SimpleHub : Hub
{
public void SendSimple(string message, detail)
{
Clients.All.notifySimple (message, detail);
}
}
Default parameter names in callback response:
// Client
SwiftR.connect("http://localhost:8080") { connection in
let simpleHub = connection.createHubProxy("simpleHub")
// Event handler
simpleHub.on("notifySimple") { args in
let message = args!["0"] as! String
let detail = args!["1"] as! String
println("Message: \(message)\nDetail: \(detail)")
}
}
Custom parameter names in callback response:
// Client
SwiftR.connect("http://localhost:8080") { connection in
let simpleHub = connection.createHubProxy("simpleHub")
// Event handler
simpleHub.on("notifySimple", parameters: ["message", "detail"]) { args in
let message = args!["message"] as! String
let detail = args!["detail"] as! String
println("Message: \(message)\nDetail: \(detail)")
}
}
// Server
public class ComplexMessage
{
public int MessageId { get; set; }
public string Message { get; set; }
public string Detail { get; set; }
public IEnumerable<String> Items { get; set; }
}
// Server
public class ComplexHub : Hub
{
public void SendComplex(ComplexMessage message)
{
Clients.All.notifyComplex (message);
}
}
// Client
var complexHub: Hub!
SwiftR.connect("http://localhost:8080") { [weak self] connection in
self?.complexHub = connection.createHubProxy("complexHub")
self?.complexHub.on("notifyComplex") { args in
let m: AnyObject = args!["0"] as AnyObject!
println(m)
}
}
let message = [
"messageId": 1,
"message": "Complex Test",
"detail": "This is a complex message",
"items": ["foo", "bar", "baz"]
]
// Invoke server method
complexHub.invoke("sendComplex", parameters: [message])
// Server
app.MapSignalR<MyConnection> ("/echo");
...
public class MyConnection : PersistentConnection
{
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
return Connection.Broadcast(data);
}
}
// Client
var persistentConnection: SignalR!
persistentConnection = SwiftR.connect("http://localhost:8080/echo", connectionType: .Persistent) { connection in
connection.received = { data in
println(data!)
}
}
// Send data
persistentConnection.send("Persistent Connection Test")
By default, SignalR will choose the best transport available to you. You can also specify the transport method:
SwiftR.transport = .Auto // This is the default
SwiftR.transport = .WebSockets
SwiftR.transport = .ServerSentEvents
SwiftR.transport = .ForeverFrame
SwiftR.transport = .LongPolling
SwiftR exposes the following SignalR events:
SwiftR.connect("http://localhost:8080") { connection in
...
connection.started = { println("started") }
connection.connected = { println("connected: \(connection.connectionID)") }
connection.connectionSlow = { println("connectionSlow") }
connection.reconnecting = { println("reconnecting") }
connection.reconnected = { println("reconnected") }
connection.disconnected = { println("disconnected") }
}
Upon a disconnected
event, SwiftR automatically tries to reconnect after five seconds.
Use the stop()
and start()
methods to manage connections manually.
var myConnection: SignalR!
myConnection = SwiftR.connect("http://localhost:8080") { connection in
let simpleHub = connection.createHubProxy("simpleHub")
// Event handler
simpleHub.on("notifySimple") { args in
let message = args!["0"] as! String
let detail = args!["1"] as! String
println("Message: \(message)\nDetail: \(detail)")
}
}
...
if myConnection.state == .Connected {
myConnection.stop()
} else if myConnection.state == .Disonnected {
myConnection.start()
}
... // Or...
SwiftR.stopAll()
SwiftR.startAll()
public enum State {
case Connecting
case Connected
case Disconnected
}
...
if myConnection.state == .Connecting {
// Do something...
}
SwiftR.connect("http://localhost:8080") { connection in
connection.queryString = ["foo": "bar"]
...
}
SwiftR.connect("http://localhost:8080") { connection in
connection.headers = ["X-MyHeader1": "Value1", "X-MyHeader2", "Value2"]
...
}
SwiftR will send any cookies in your app's NSHTTPCookieStorage to SignalR. You can also set cookies manually:
let cookieProperties = [
NSHTTPCookieName: "Foo",
NSHTTPCookieValue: "Bar",
NSHTTPCookieDomain: "myserver.com",
NSHTTPCookiePath: "/",
]
let cookie = NSHTTPCookie(properties: cookieProperties)
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie!)
SwiftR.connect("http://localhost:8080") { connection in
...
connection.error = { error in println(error!) }
/*
{
readyState = 0;
status = 0;
statusText = error;
}
*/
}
SwiftR is released under the MIT license. See LICENSE for details.