Skip to content

jaydeboer/SwiftR

 
 

Repository files navigation

SwiftR

A Swift client for SignalR. Supports hubs and persistent connections.

How does it work?

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.

UIWebView or WKWebView?

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

Installation

CocoaPods:

use_frameworks!
pod 'SwiftR'

Carthage:

github 'adamhartford/SwiftR'

Server Example

See https://github.com/adamhartford/SignalRDemo for a sample self-hosted SignalR application.

Simple Example (Hub)

// 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)")
    }
}

Complex Example (Hub)

// 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])

Persistent Connections

// 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")

Transport Method

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

Connection Lifetime Events

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.

Stop/Start Connection

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()

Connection State

public enum State {
    case Connecting
    case Connected
    case Disconnected
}

...

if myConnection.state == .Connecting {
    // Do something...
}

Sending information to SignalR

Query String

SwiftR.connect("http://localhost:8080") { connection in
    connection.queryString = ["foo": "bar"]
    ...
}

Custom Headers (Non-WebSocket Only)

SwiftR.connect("http://localhost:8080") { connection in
    connection.headers = ["X-MyHeader1": "Value1", "X-MyHeader2", "Value2"]
    ...
}

Cookies (UIWebView Only)

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!)

Error Handling

SwiftR.connect("http://localhost:8080") { connection in
    ...

    connection.error = { error in println(error!) }
    
    /*
    {
        readyState = 0;
        status = 0;
        statusText = error;
    }
    */
}

License

SwiftR is released under the MIT license. See LICENSE for details.

About

Swift client for SignalR (iOS and Mac)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 87.4%
  • JavaScript 7.4%
  • Objective-C 3.3%
  • Ruby 1.9%