Giter VIP home page Giter VIP logo

signalr-client-swift's Introduction

SwiftSignalRClient

A Swift SignalR Client for the Asp.Net Core version of SignalR

Before filing an issue please check Frequently Asked Questions

Everything you need to know about using the Swift SignalR Client in under 60 minutes

Installation

Cocoapods

Add the following lines to your Podfile:

use_frameworks!
pod 'SwiftSignalRClient'

Then run:

pod install

Swift Package Manager

The easiest way to is to use Use XCode UI (File -> Add Packages...)

Alternatively, add the following to your Package dependencies:

.package(url: "https://github.com/moozzyk/SignalR-Client-Swift", .upToNextMinor(from: "0.9.0")),

Then include "SignalRClient" in your target dependencies. For example:

.target(name: "MySwiftPackage", dependencies: ["SignalRClient"]),

Carthage

Add the following lines to your Cartfile:

github "moozzyk/SignalR-Client-Swift"

Then run:

carthage update

Usage

Add import SwiftSignalRClient (or import SignalRClient if you are using Swift Package Manager) to swift files you would like to use the client in.

A typical implementation looks like the following:

import Foundation
import SwiftSignalRClient

public class SignalRService {
    private var connection: HubConnection
    
    public init(url: URL) {
        connection = HubConnectionBuilder(url: url).withLogging(minLogLevel: .error).build()
        connection.on(method: "MessageReceived", callback: { (user: String, message: String) in
            do {
                self.handleMessage(message, from: user)
            } catch {
                print(error)
            }
        })
        
        connection.start()
    }
    
    private func handleMessage(_ message: String, from user: String) {
        // Do something with the message.
    }
}

More detailed user's guides:

Examples

There are several sample projects in the Examples folder. They include:

  • SignalRClient.xcodeproj

    An Xcode workspace that has compiled libraries for macOS (OSX) and iOS, along with the Application targets 'ConnectionSample', 'HubSample', and 'HubSamplePhone'.

  • TestServer

    A .Net solution that the unit tests and samples can be run against.

    The TestServer Requires .NET Core SDK 3.0.100 or later.

    To run, navigate to the TestServer folder and execute the following in the terminal:

    % npm install
    % dotnet run

    When running the TestServer project on macOS Monterey (12.0 or greater), you may encounter the error: "Failed to bind to address http://0.0.0.0:5000: address already in use.". This is due to Apple now advertising an 'AirPlay Receiver' on that port. This port can be freed by disabling the receiver: Navigate to System Preferences > Sharing and uncheck AirPlay Receiver.

Hits

HitCount

signalr-client-swift's People

Contributors

abakhtin avatar aj-bartocci avatar andre-alves avatar brentatresultstack avatar davidjrobertson avatar dependabot[bot] avatar dkornev avatar gpotari avatar guillermociquecom avatar imjamper avatar joshr604 avatar katexe avatar kenrf avatar marwendoukh avatar mattgallagher avatar mattspark170 avatar maxim-kiselev avatar miranl avatar moozzyk avatar mythicbits avatar ninban avatar ovidiuadorian-yonder avatar richardpiazza avatar trykovyura avatar wacumov avatar yuryniakhai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

signalr-client-swift's Issues

HubConnectionBuilder not in POD (0.2.0)

The class HubConnectionBuilder is not available in the current POD release. I do see in the master branch that it's been updated, but this update is not available in cocoa pods.

Custom Negotiation Response Key Handling

Hi there , What can we do when server negotiation response keys are different from hard-coded keys in framework ? for example "ConnectionId" instead of connectionId.🧐
Thanks.

Investigate partial responses

Currently the assumption is that received messages are not fragmented. Investigate if this assumption is safe (e.g. for big messages) and if not add support for handling partial messages.

Error building using Carthage

Looks like there's an issue with building this repo using Carthage on master.

Here's what my Cartfile looks like:

github "moozzyk/SignalR-Client-Swift"

$carthage update --platform iOS
*** Building scheme "iOS SignalRClient" in SignalRClient.xcworkspace
Build Failed
	Task failed with exit code 65:
	/usr/bin/xcrun xcodebuild -workspace /Users/anuj/projects/ios/Eva/ios/Eva/Carthage/Checkouts/SignalR-Client-Swift/SignalRClient.xcworkspace -scheme iOS\ SignalRClient -configuration Release -derivedDataPath /Users/anuj/Library/Caches/org.carthage.CarthageKit/DerivedData/10.2.1_10E1001/SignalR-Client-Swift/0.4.2 -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/dj/1hvxkr256vlcd2qft9ww4jq00000gn/T/SignalR-Client-Swift SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/anuj/projects/ios/Eva/ios/Eva/Carthage/Checkouts/SignalR-Client-Swift)

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/dj/1hvxkr256vlcd2qft9ww4jq00000gn/T/carthage-xcodebuild.RFYYqd.log

Then I inspect the log file for build errors:

$cat /var/folders/dj/1hvxkr256vlcd2qft9ww4jq00000gn/T/carthage-xcodebuild.RFYYqd.log | grep error:

error: /Users/anuj/projects/ios/Eva/ios/Eva/Carthage/Checkouts/SignalR-Client-Swift/Pods/Target Support Files/Pods-iOS SignalRClient/Pods-iOS SignalRClient.release.xcconfig: unable to open file (in target "iOS SignalRClient" in project "SignalRClient") (in target 'iOS SignalRClient')
error: /Users/anuj/projects/ios/Eva/ios/Eva/Carthage/Checkouts/SignalR-Client-Swift/Pods/Target Support Files/Pods-iOS SignalRClient/Pods-iOS SignalRClient.release.xcconfig: unable to open file (in target "iOS SignalRClient" in project "SignalRClient") (in target 'iOS SignalRClient')
error: /Users/anuj/projects/ios/Eva/ios/Eva/Carthage/Checkouts/SignalR-Client-Swift/Pods/Target Support Files/Pods-iOS SignalRClient/Pods-iOS SignalRClient.release.xcconfig: unable to open file (in target "iOS SignalRClient" in project "SignalRClient") (in target 'iOS SignalRClient')

Remaining work

  • races (start/stop, start/close/stop)

  • transports:

    • longpolling (see SignalR source - there is some special logic when closing the LP transport)
    • serverSentEvents
    • binary transfer mode
  • extension points

    • enabling non-JSON protocols
    • MessagePack (requires binary transfer mode)
  • protocol

    • streaming
    • cancellation
  • logging

  • restartable instance

  • access_token (jwt)

  • cookies

  • headers

  • certificates

  • credentials

  • connection options

  • JSON serialization options (e.g. camelCase). Needed?

  • Post alpha2 breaking changes:

    • protocol changes
    • OPTIONS -> POST
    • remove negotiate when websockets transport explicitly requested
    • restartable connection
  • Post preview 2 changes

    • protocol changes
    • long polling and SSE now can know that connection has started
  • Post RC1 changes:

  • client side pings

  • Post RTM:

  • keep alive

Compilation Error

Hi Pawel,
Thanks for the SignalRClient. When I integrate SwiftSignalRClient as a framework, the compilation and execution of the project is successful to establish SignalR connection.
But when I add the code files from SignalRClient folder to my project and try to compile it, I am ending up in compilation errors. Kindly help me in achieving this to execute my project successfully.
The following are the compilation errors for your reference:

Undefined symbols for architecture arm64:
"_inflate", referenced from:
XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B).inflate(Swift.UnsafePointer<Swift.UInt8>, length: Swift.Int, final: Swift.Bool) throws -> (p: Swift.UnsafeMutablePointer<Swift.UInt8>, n: Swift.Int) in WebSocket.o
"_zlibVersion", referenced from:
XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int) -> XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
XXXX.(Deflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int, memLevel: Swift.Int) -> XXXX.(Deflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
"deflateInit2", referenced from:
XXXX.(Deflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int, memLevel: Swift.Int) -> XXXX.(Deflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
"_inflateEnd", referenced from:
XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B).deinit in WebSocket.o
"_deflateEnd", referenced from:
XXXX.(Deflater in _141339CDE6DAD76818B2487D3534D40B).deinit in WebSocket.o
"inflateInit2", referenced from:
XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int) -> XXXX.(Inflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Invalid Handshake Response

Hi ,

Whenever I will trying to connect with server,It throws an error "Invalid Handshake Response".

let alert = UIAlertController(title: "Enter your Name", message:"", preferredStyle: UIAlertControllerStyle.alert)
alert.addTextField() { textField in textField.placeholder = "Name"}
let OKAction = UIAlertAction(title: "OK", style: .default) { action in
    self.name = alert.textFields?.first?.text ?? "John Doe"
            
    self.chatHubConnectionDelegate = ChatHubConnectionDelegate(controller: self)
    self.chatHubConnection = HubConnection(url: URL(string: self.serverUrl)!)
                               
    self.chatHubConnection!.delegate = self.chatHubConnectionDelegate
    self.chatHubConnection!.on(method: "newMessage", callback: {args, typeConverter in
        let user = try! typeConverter.convertFromWireType(obj: args[0], targetType: String.self)
        let message = try! typeConverter.convertFromWireType(obj: args[1], targetType: String.self)
        self.appendMessage(message: "\(user!): \(message!)")
     })
     self.chatHubConnection!.start()        
}
alert.addAction(OKAction)
self.present(alert, animated: true)

After recent update (0.6.1) connection fails - returns InvalidResponse(HTTP/1.1 404 Not Found)

Hi!

It appears that something has changed not for the better in my case, because websocket connection fails to get established.

2019-07-03T12:49:47.377Z debug: Negotiate completed with OK status code
2019-07-03T12:49:47.377Z debug: Negotiate response: {"connectionId":"BrBwByiNWeTQ9Y0zJhhxZQ","availableTransports":[{"transport":"WebSockets","transferFormats":["Text","Binary"]},{"transport":"ServerSentEvents","transferFormats":["Text"]},{"transport":"LongPolling","transferFormats":["Text","Binary"]}]}
2019-07-03T12:49:47.382Z debug: Negotation response received
2019-07-03T12:49:53.665Z info: Starting WebSocket transport
2019-07-03T12:49:54.016Z info: WebSocket error. Error: InvalidResponse(HTTP/1.1 404 Not Found)
2019-07-03T12:49:54.017Z info: Transport closed
2019-07-03T12:49:54.018Z debug: Attempting to chage state from: '(nil)' to: 'stopped'
2019-07-03T12:49:54.019Z debug: Changing state to: 'stopped' succeeded
2019-07-03T12:49:54.020Z debug: Previous state connecting
2019-07-03T12:49:54.020Z debug: Leaving startDispatchGroup (transportDidClose(_:): 240)
2019-07-03T12:49:54.020Z debug: Invoking connectionDidFailToOpen
[WebSocket] Failed to connect to server: (The operation couldn’t be completed. (SwiftSignalRClient.WebSocketError error 4.)

Any guesses why it might work out like that?
Never had that "InvalidResponse(HTTP/1.1 404 Not Found)" on 0.4.1.
Considering making a rollback.

Some backtrace – code which worked before:

        let wssEndpoint = networkConfig.websocketBaseUrl // Acquiring WS url.
        let url = "\(wssEndpoint)/hub/?access_token=\(accessToken)&id=\(connectionId)" // In our scheme, access token and connectionId is passed here.
        let socketUrl = URL(string: url)!

        let chatHubConnection = HubConnectionBuilder(url: socketUrl)
            .withLogging(minLogLevel: .debug)

           /// The following lines were added as of 0.6.1:
            .withHttpConnectionOptions(configureHttpOptions: { (options) in
                options.accessTokenProvider = { accessToken }
            })

            .build()

        /// Some event subscription, etc
        /// ...
        chatHubConnection.delegate = self
        chatHubConnection.start()

Thanks in advance for any input.

Handshake Error

Hi, my team using ASP.Net Core on backend. And JS module works fine with it. When i try to connect with SignalR-Client-Swift, then ws connection opened and first message as handshake comes "{"type":6}\u{1E}". it is normal parsable json. But your code says if there is not empty json in handshake then it is error and closes connection.

private static func parseHandshakeResponse(handshakeResponse: Data) -> Error? {
        do {
            if let handshakeResponseJson = try JSONSerialization.jsonObject(with: handshakeResponse) as? NSDictionary {
                if handshakeResponseJson.count == 0 {
                    return nil
                }

                if handshakeResponseJson.count == 1, let errorMessage = handshakeResponseJson.value(forKey: "error") as? String {
                    return SignalRError.handshakeError(message: errorMessage)
                }
            }
        } catch {
            return error
        }

        return SignalRError.handshakeError(message: "Invalid handshake response.")
    }

What can i do to connect normally?
I creating connection by 2 lines of code (rest of lines is delegate)

chatHubConnection = HubConnection(url: URL(string:"MYHOST")!, hubProtocol: JSONHubProtocol());
chatHubConnection?.delegate = self

How to make the HubConnection automatically reconnect after disconnect

Hi,

The HubConnection will disconnect if, say, I switch from WIFI to a cellular network.
This is fine, however it would just be useful if it automatically reconnects over the cellular network.
At the moment I listen for disconnect callbacks (connectionDidClose) and invoke a timer which attempts to open a new connection every 3 seconds, on successful connection the timer is invalidated.

However this is not quite the solution I'm looking for.
I am hoping that I am missing a simple flag that I can toggle on to enable reconnection on disconnect.
If this is against the design of the client then not to worry.

If there is a better way about going about this your suggestions would be greatly appreciated.

Kind regards
Ben

invocationDidComplete: always give me nil object - iOS

chatHubConnection?.invoke(method: "Market", arguments: [OrderID], returnType: NSDictionary.self, invocationDidComplete: { (args, error) in
if error == nil {
print(args ?? "Not Found")
} else {
print(error?.localizedDescription ?? "Error")
}
})

Support Swift 5

SWIFT_VERSION '3.3' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'SwiftSignalRClient')

invoke with returnType: Data throwing error of unsupported type

I'm trying to get a list of Channels from signalR on an invoke method with a returnType of Data and then use the Decodable protocol to then parse the result into an array of channels. However the client is getting an error or Unsupported type. I can use Any as the result, but then I would be unable to use the Codable protocol.

    self.chatHubConnection?.invoke(method: "ListChannels", arguments: ["My Channels", 0, 0], returnType: Data.self ) { result, error in
        if error != nil {
            print("We got an error", error)
        } else {
            let channelList = try! JSONDecoder().decode([Channel].self, from: result!)
            print(channelList)
        }
    }

Is there anyway to authenticate yet? :)

I'm not an iOS developer, though i'm thinking of using SignalR in a project, is it possible to authenticate via query string with this client, and are you using this in any projects yourself?

Cannot connect to server

I can't connect to your server because of this issue

/Users/mac/Downloads/SignalR-Client-Swift-master/TestServer/TestServer.csproj(20,5): error MSB3030: Could not copy the file "/Users/mac/Downloads/SignalR-Client-Swift-master/TestServer/node_modules/@aspnet/signalr/dist/browser/signalr.js" because it was not found.

The build failed. Please fix the build errors and run again.

Handshake data out of bounds error

Hello,
Im working on a chat socket with signalIR at one iOS application,
The handshakeResponse is crashing for data created from an empty JSON, it's getting the wrong idx.
My response example:
"{}\u{1E}"
idx = 30
data[0..<30] => crash

Crashing at parseHandshakeResponse(data: Data) from HandshakeProtocol class

static func parseHandshakeResponse(data: Data) -> (Error?, Data) {
#if swift(>=5.0)
if let idx = data.firstIndex(where: {$0 == 0x1e}) {
let error = parseHandshakeResponse(handshakeResponse: data[0..<idx])
return (error, data.dropFirst(idx + 1))
}
#else
if let idx = data.first(where: {$0 == 0x1e}) {
let error = parseHandshakeResponse(handshakeResponse: data[0..<idx])
return (error, data.dropFirst(Int(idx + 1)))
}
#endif
return (SignalRError.handshakeError(message: "Received partial handshake response."), data)
}

iOS Build has no SignalRClient framework

Am I missing something? When running "Carthage update --platform iOS" a SocketRocket framework is generated but not a SignalRClient.framework. Only the Mac platform build seems to have a SignalRClient.framework generated.

negotiate protocol changed in dotnetcore 2.1

Im trying to use this with a signalR server written in dotnet core 2.1.303 and its failing to connect. It looks like some changes were made to the underlying protocol in SignalR.

I am getting 405 error when using this client. As far as i can tell you are passing settings and this is no longer how it works. I get the same error in postman but if I just POST to {hubname}/negotiate with no other params then it returns me JSON with the options the server supports and a connectionId.

Minimum deployment target is ios11.2

Hi Moozzyk,
When I try to run the SignalR-Client-Swift in below the iOS 11.2 version ,It gives an error and says Module file's minimum deployment target is ios11.2 v11.2.

Undefined symbols for architecture arm64

The code which worked 3 months back is throwing the below build error.

Kindly help me in this.

Undefined symbols for architecture arm64:
"_inflate", referenced from:
MyFramework.(Inflater in 141339CDE6DAD76818B2487D3534D40B).inflate(: Swift.UnsafePointer<Swift.UInt8>, length: Swift.Int, final: Swift.Bool) throws -> (p: Swift.UnsafeMutablePointer<Swift.UInt8>, n: Swift.Int) in WebSocket.o
"_zlibVersion", referenced from:
MyFramework.(Inflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int) -> MyFramework.(Inflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
MyFramework.(Deflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int, memLevel: Swift.Int) -> MyFramework.(Deflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
"deflateInit2", referenced from:
MyFramework.(Deflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int, memLevel: Swift.Int) -> MyFramework.(Deflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
"_inflateEnd", referenced from:
MyFramework.(Inflater in _141339CDE6DAD76818B2487D3534D40B).__deallocating_deinit in WebSocket.o
"_deflateEnd", referenced from:
MyFramework.(Deflater in _141339CDE6DAD76818B2487D3534D40B).__deallocating_deinit in WebSocket.o
"inflateInit2", referenced from:
MyFramework.(Inflater in _141339CDE6DAD76818B2487D3534D40B).init(windowBits: Swift.Int) -> MyFramework.(Inflater in _141339CDE6DAD76818B2487D3534D40B)? in WebSocket.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

adding access token to hub connection

When calling .Start() on the hub connection I'm getting a 401 unauthorized. This is because the server is expecting a token (which I have in the keychain on the device), but I'm unsure on how to pass this during the /negotiate call.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.