Code Monkey home page Code Monkey logo

socket.io-client-swift's Introduction

Build Status

Socket.IO-Client-Swift

Socket.IO-client for iOS/OS X.

Example

import SocketIO

let manager = SocketManager(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true), .compress])
let socket = manager.defaultSocket

socket.on(clientEvent: .connect) {data, ack in
    print("socket connected")
}

socket.on("currentAmount") {data, ack in
    guard let cur = data[0] as? Double else { return }
    
    socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in
        if data.first as? String ?? "passed" == SocketAckValue.noAck {
            // Handle ack timeout 
        }

        socket.emit("update", ["amount": cur + 2.50])
    }

    ack.with("Got your currentAmount", "dude")
}

socket.connect()

Features

  • Supports Socket.IO server 2.0+/3.0+/4.0+ (see the compatibility table)
  • Supports Binary
  • Supports Polling and WebSockets
  • Supports TLS/SSL

FAQS

Checkout the FAQs for commonly asked questions.

Checkout the 12to13 guide for migrating to v13+ from v12 below.

Checkout the 15to16 guide for migrating to v16+ from v15.

Installation

Requires Swift 4/5 and Xcode 10.x

Swift Package Manager

Add the project as a dependency to your Package.swift:

// swift-tools-version:4.2

import PackageDescription

let package = Package(
    name: "socket.io-test",
    products: [
        .executable(name: "socket.io-test", targets: ["YourTargetName"])
    ],
    dependencies: [
        .package(url: "https://github.com/socketio/socket.io-client-swift", .upToNextMinor(from: "15.0.0"))
    ],
    targets: [
        .target(name: "YourTargetName", dependencies: ["SocketIO"], path: "./Path/To/Your/Sources")
    ]
)

Then import import SocketIO.

Carthage

Add this line to your Cartfile:

github "socketio/socket.io-client-swift" ~> 15.2.0

Run carthage update --platform ios,macosx.

Add the Starscream and SocketIO frameworks to your projects and follow the usual Carthage process.

CocoaPods 1.0.0 or later

Create Podfile and add pod 'Socket.IO-Client-Swift':

use_frameworks!

target 'YourApp' do
    pod 'Socket.IO-Client-Swift', '~> 15.2.0'
end

Install pods:

$ pod install

Import the module:

Swift:

import SocketIO

Objective-C:

@import SocketIO;

Detailed Example

A more detailed example can be found here

An example using the Swift Package Manager can be found here

License

MIT

socket.io-client-swift's People

Contributors

alevinru avatar aputinski avatar atlcto avatar banjun avatar bingfengzhu avatar callumoz avatar cfkevinref avatar craigkj312 avatar darrachequesne avatar davbeck avatar dickverbunt avatar drekka avatar georgenavarro avatar hankbao avatar headlessme avatar hfossli avatar ivangamov avatar kevinmartin avatar marinh avatar mephi1984 avatar musicabbage avatar nachosoto avatar naderio avatar nuclearace avatar onesman7 avatar pdupris avatar petergam avatar tbaranes avatar vonox7 avatar yannickl 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  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

socket.io-client-swift's Issues

Plus signs ("+") is not URL encoded

Hi there,

I have an issue when I connect to the server using the connectWithParams method with params which contains plus signs ("+").
I need to send a date with the GMT indicator (e.g. '+001') but as the "+" is not URL encoded nodejs think it is just a space.

I'll pull a patch soon to avoid this problem.

Thanks for the great lib.

Multiple reconnection attempts triggers multiple disconnection events

First of all, I love the stability gained from using this new wonderful library! It's quicker and more reliable than the unofficial framework I used before. 👍

However, i'm experiencing a glitch which causes multiple reconnectionAttempts to trigger a disconnect-event on the server for the failed attempts. It is best described with an example.

The case is this:

  1. SwiftIO is connected to a node socket.io server - it's all good
  2. I stop the server, wait 10 seconds, and start the server again
  3. SwiftIO starts reconnecting - in this example it triggers reconnectAttempt 3 times before reconnecting
  4. The server acknowledges all 3 attempts by triggering the connection-event on the server 3 times
  5. After approx. 25 seconds the disconnect-event is triggered on the server for the 2 failed reconnects

My iOS code (in obj-c sorry):

    NSMutableDictionary *socketParams = [[NSMutableDictionary alloc] init];
    socketParams[@"username"] = @"username";

    NSMutableDictionary *socketOptions = [[NSMutableDictionary alloc] init];
    socketOptions[@"reconnectWait"] = @5;
    socketOptions[@"timeout"] = @3; // undocumented - just trying my luck :) 
    socketOptions[@"connect timeout"] = @3; // undocumented - just trying my luck :) 
    socketOptions[@"connectTimeout"] = @3; // undocumented - just trying my luck :)     
    socketOptions[@"forceWebsockets"] = @TRUE;

    SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:@"localhost:1337" options:socketOptions];

    [socket connectWithParams:(socketParams)];


    [socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"socket connected (or reconnected)");
    }];

    [socket on: @"reconnectAttempt" callback:^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"Reconnect attempt");
    }];

    [socket on: @"reconnect" callback:^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"socket starting reconnect");
    }];

My server code looks like this:

io.on('connection', function (socket) {
    console.log('connection triggered');

    socket.on('disconnect', function () {
        console.log('disconnect triggered');
    })
});

Is it working as intended? I don't think that a disconnect event should be triggered on failed connection attempts - e.g. there's no connection ergo no disconnect to invoke. 😄

self gets released while dispatch_async block executes.

I saw lots of dispatch_async() { [weak self] .... } blocks in code base where within those blocks, self is being forced unwrapped.

This can be a dangerous act if you don't retain those weak self properly by using if let self = self and my app crashes one out of 5 times because self was released while dispatch_async blocks were executing

for example,

SocketEngine.swift

public func write(msg:String, withType type:PacketType, withData data:ContiguousArray<NSData>?) {
        dispatch_async(self.emitQueue) {[weak self] in

            if self == nil || !self!.connected {
                return
            }

            if self!.websocket {
                SocketLogger.log("Writing ws: \(msg):\(data)", client: self!)
                self?.sendWebSocketMessage(msg, withType: type, datas: data)
            } else {
                SocketLogger.log("Writing poll: \(msg):\(data)", client: self!)
                self?.sendPollMessage(msg, withType: type, datas: data)
            }
        }
    }

Code checks if self is nil at the beginning and executes accordingly. But since you never used strong reference to that self after checking it isn't nil, there still is a possibility that it crashes app if self was released while, say, SocketLogger.log("Writing ws: \(msg):\(data)", client: self!) was executing since you try force unwrapping on self.

Safer and right way to do it is to use, if let self = self { } else { }. This way you retain pointer to self as long as newly created self is being used by the given block. I recommend switching from above pattern to if let pattern for all your codebase.

Swift Compiler Error

I am getting a lot of Swift Compiler issue after install the library using cocoapod:

/Users/Chris/Documents/Development/Xcode/SIOSwift/Pods/Socket.IO-Client-Swift/SwiftIO/SocketEngine.swift:29:16: error: 'countElements' has been renamed to count
return countElements(self)
^~~~~~~~~~~~~
count
Swift.countElements:1:36: note: 'countElements' has been explicitly marked unavailable here
@Availability(, unavailable) func countElements(x: T) -> T.Index.Distance
^
/Users/Chris/Documents/Development/Xcode/SIOSwift/Pods/Socket.IO-Client-Swift/SwiftIO/SocketEngine.swift:134:43: error: 'AnyObject' is not convertible to 'String'; did you mean to use 'as!' to force downcast?
let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters(
~~~~~~^~~~~~~~~
as!
/Users/Chris/Documents/Development/Xcode/SIOSwift/Pods/Socket.IO-Client-Swift/SwiftIO/SocketEngine.swift:226:23: error: 'countElements' has been renamed to count
let len = countElements(packet)
^~~~~~~~~~~~~
count
Swift.countElements:1:36: note: 'countElements' has been explicitly marked unavailable here
@Availability(
, unavailable) func countElements(x: T) -> T.Index.Distance
^
/Users/Chris/Documents/Development/Xcode/SIOSwift/Pods/Socket.IO-Client-Swift/SwiftIO/SwiftRegex.swift:141:28: warning: closure parameter prior to parameters with default arguments will not be treated as a trailing closure
func substituteMatches(substitution: (NSTextCheckingResult, UnsafeMutablePointer) -> String,

Swift 1.2 PodSpec branch.

After installing socket.io-client-swift with Podfile - the installed version of this lib was from master branch, not from 1.2 branch. How do we change it ?

How to pass data to emitObjc?

what is the right way to emit with data?
emitObjc accepts only an NSArray.

    [socket emitObjc:@"echo" withItems:@[@"echo test"]];

how do i pass a dictionary like this?

[self.socketIO sendEvent:@"add-user" withData:@{@"username":self.username}];

onAny in Objective-C

can you please give an example of how onAny works in Objective-C
code auto completes this way:

how do I access event and data received?

[socket onAny:^{

}];

Thanks

Client connecting multiple times when proxied through nginx

Sometimes it connects more than 3 times. If I connect directly to the socket.io it connects only once.

multiple connects:

    10.0.1.236 - - [27/Mar/2015:10:27:03 -0700] "GET /socket.io/?transport=polling&b64=1         HTTP/1.1" 200 100 "-" "socket/1 CFNetwork/711.2.23 Darwin/14.0.0"
    10.0.1.236 - - [27/Mar/2015:10:27:03 -0700] "GET /socket.io/?transport=polling&sid=vb1yUHmUr59l6el6AAAP HTTP/1.1" 200 4 "-" "socket/1         CFNetwork/711.2.23 Darwin/14.0.0"
    10.0.1.236 - - [27/Mar/2015:10:27:03 -0700] "POST /socket.io/?transport=polling&sid=vb1yUHmUr59l6el6AAAP HTTP/1.1" 400 45 "-" "socket/1         CFNetwork/711.2.23 Darwin/14.0.0"

Objective-C client code:

  - (void)viewDidLoad {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
      socket = [[SocketIOClient alloc] initWithSocketURL:@"http://socket.xxx.com"       options:@{@"nsp":@"kwik"}];

      [socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
          NSLog(@"connected");

          [socket emitObjc:@"add-user" withItems:@[ @{@"username":@"username"} ] ];
      }];
      [socket on:@"data" callback:^(NSArray* data, void (^ack)(NSArray*)) {
          NSLog(@"data:%@", data);
      }];
      [socket connect];
  }

nginx config:

server {
    listen       80;
    server_name socket.xxx.com;
    location /socket.io {
        proxy_pass http://localhost:5000/socket.io;
        proxy_redirect off;
        proxy_buffering off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

How do I register for unrequested updates?

When the socket sends me something and I don't expect it, how can I log that information?

It doesn't look like any of the "Events" are for that, and I don't see a way to register myself as a delegate to get updates.

I can Emit a request and get back an ack, but what about updates that I didn't ask for?

Thanks!

Problem with emitWithAck being called consecutively

Hi,

I have a node-js server running, everything is fine, except for one little problem.
When emitWithAck is called twice, one after the other, the second emit fails one out of every ten times.
Each event emitted is different, and the server doesn't seem to receive the second event at all when it fails.
If I swap the 2 emitWithAck's around, then it's the new second one that fails.

My code looks like this:

self.socket.emitWithAck("event1", ...)
self.socket.emitWithAck("event2", ...)

I hope that's enough information, even though I doubt it, it's a start at least ;)

Callum

obj-c interface

Did SocketIOClient.swift L 217

public func emitObjc(event:String, withItems items:[AnyObject]) {

should be

public func emitObjc(event:String, withItems items:AnyObject) {

?

Using this client with self signed certificates

I'd need to pass a optional NSURLSessionDelegate to the societ client and in turn to the socket engine so that this can be used to handle the call "func URLSession(session: NSURLSession,
task: NSURLSessionTask,
didReceiveChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition,
NSURLCredential!) -> Void)"

This will help dealing with Servers having self-signed certificates that is typically the case in SSL servers in dev mode.

I have made the code changes locally - could i request to pull a branch in which these changes can be made

Allow option to specify custom socket.io url path.

First of all, amazing job here. Now I don't need to rely on creating webview to handle client side!

Currently, it seems like /socket.io, (default socket.io server path) is attached to the end of passed socketURL during init.

Since in socket.io server, path can be customized by passing 'path' key to options object, client should also support it.

I personally prefer to use '/io' path instead of '/socket.io' simply for simplicity and now returned url is "(SERVER_URL)/io/socket.io".

Error parsing message: 1

Ive got these message when I tried emit to server.
socket.on("connect") {data, ack in println("socket connected") socket.emit("conf")

Do you know what is message 1?

Basic client crashes when connected with namespace nsp option

If nsp option is added, it crashes. This same code works without nsp.

  - (void)viewDidLoad {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
      socket = [[SocketIOClient alloc] initWithSocketURL:@"http://10.0.1.236:4000" options:@{@"nsp":@"/kwik"}];

      [socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
          NSLog(@"connected");
          [socket emitObjc:@"echo" withItems:@[@"echo test"]];
          [[socket emitWithAckObjc:@"ackack" withItems:@[@"test"]] onAck:0 withCallback:^(      NSArray* data) {
              NSLog(@"Got data");
          }];
      }];
      [socket on:@"data" callback:^(NSArray* data, void (^ack)(NSArray*)) {
          NSLog(@"data:%@", data);
      }];
      [socket connect];
  }

Here is screenshot of crashlog.

screen shot 2015-03-26 at 2 20 24 pm

WebSocket.swift:602. EXC_BAD_ACCESS KERN_INVALID_ADDRESS (Crashed: engineHandleQueue)

Hi,

Our app is written in ObjC for iOS 7+, but we are getting this crash. This crash appears in a different place then previously reported:

Thread : Crashed: engineHandleQueue
0 libswiftCore.dylib 0x000000010131d814 swift_unknownRetainUnowned + 40
1 DevAuctionataLive 0x00000001000b86f4 DevAuctionataLive.SocketEngine.(parseEngineMessage in _4DCD037EFB1C27BE04F82A88FF07B400) (DevAuctionataLive.SocketEngine)(Swift.String) -> () (SocketEngine.swift:470)
2 DevAuctionataLive 0x00000001000b86f4 DevAuctionataLive.SocketEngine.(parseEngineMessage in _4DCD037EFB1C27BE04F82A88FF07B400) (DevAuctionataLive.SocketEngine)(Swift.String) -> () (SocketEngine.swift:470)
3 DevAuctionataLive 0x00000001000bb744 protocol witness for DevAuctionataLive.WebSocketDelegate.websocketDidReceiveMessage (DevAuctionataLive.WebSocketDelegate.Self)(DevAuctionataLive.WebSocket, text : Swift.String) -> () in conformance DevAuctionataLive.SocketEngine : DevAuctionataLive.WebSocketDelegate (SocketEngine.swift:605)
4 DevAuctionataLive 0x000000010010df60 DevAuctionataLive.WebSocket.((processResponse in _8EBB333CEB46C95CC2731D7C6BDBCF21) (DevAuctionataLive.WebSocket) -> (DevAuctionataLive.WebSocket.WSResponse) -> Swift.Bool).(closure #1) (WebSocket.swift:602)
5 libdispatch.dylib 0x0000000198959994 _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x0000000198959954 _dispatch_client_callout + 16
7 libdispatch.dylib 0x00000001989640a4 _dispatch_queue_drain + 1448
8 libdispatch.dylib 0x000000019895ca5c _dispatch_queue_invoke + 132
9 libdispatch.dylib 0x0000000198966318 _dispatch_root_queue_drain + 720
10 libdispatch.dylib 0x0000000198967c4c _dispatch_worker_thread3 + 108
11 libsystem_pthread.dylib 0x0000000198b3922c _pthread_wqthread + 816

Endless loop while namespace is "/"

var socket = SocketIOClient(socketURL: host, options: ["nsp": "/"])

socket.on("connect", callback: { (data: NSArray?, am: AckEmitter?) -> Void in
})

socket.connect()

it will keep doing joinNamespace(),cause the received message is “40”

// Parses messages recieved
class func parseSocketMessage(var stringMessage:String, socket:SocketIOClient) {

    ....... 
    ....... 

    if stringMessage == "0" {
        if socket.nsp != nil {
            // Join namespace
            socket.joinNamespace()   // *repeated in here!*
            return
        } else {
            socket.didConnect()
            return
        }
    ....... 
    ....... 
}
2015-04-02 12:31:12.620 HelloSocketIO[32236:543869] outputStream: 0 9 Optional(9)
2015-04-02 12:31:12.631 HelloSocketIO[32236:543871] processResponse 40
2015-04-02 12:31:12.631 HelloSocketIO[32236:543871] parseEngineMessage: 40
2015-04-02 12:31:12.632 HelloSocketIO[32236:543871] parseSocketMessage msg: 0  nsp: Optional("/")
2015-04-02 12:31:13.944 HelloSocketIO[32236:543871] joinNamespace() /

2015-04-02 12:31:13.946 HelloSocketIO[32236:543871] outputStream: 0 9 Optional(9)
2015-04-02 12:31:13.950 HelloSocketIO[32236:543871] processResponse 40
2015-04-02 12:31:13.950 HelloSocketIO[32236:543871] parseEngineMessage: 40
2015-04-02 12:31:13.951 HelloSocketIO[32236:543871] parseSocketMessage msg: 0  nsp: Optional("/")
2015-04-02 12:32:08.789 HelloSocketIO[32236:543871] joinNamespace() /
2015-04-02 12:32:08.789 HelloSocketIO[32236:544310] dequeueWrite self.connected  true
2015-04-02 12:32:08.790 HelloSocketIO[32236:544310] outputStream: 0 7 Optional(7)
2015-04-02 12:32:08.792 HelloSocketIO[32236:544311] outputStream: 0 9 Optional(9)
2015-04-02 12:32:08.793 HelloSocketIO[32236:544311] processResponse 3
2015-04-02 12:32:08.793 HelloSocketIO[32236:544311] parseEngineMessage: 3
2015-04-02 12:32:08.795 HelloSocketIO[32236:544311] processResponse 40
2015-04-02 12:32:08.796 HelloSocketIO[32236:544311] parseEngineMessage: 40
2015-04-02 12:32:08.796 HelloSocketIO[32236:544311] parseSocketMessage msg: 0  nsp: Optional("/")

Capture self in acknowledgement callback

Hi!

First of all, thank you so much for releasing the official socket.io iOS framework. I was waiting long and hard for this baby! 😃

I have a somewhat finished app already, written in objective-c, so I'm using your framework by simply importing the swift-files with (which seems to working quite beautifully):

#import <swift_objc-Swift.h> // my testbed project is called "swift-objc"

However, I have problems addressing the "self" (= viewcontroller) in the completion handler of emits with acknowledgement. My testbed code looks like this:

- (void)viewDidLoad {
    [super viewDidLoad];    
    SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:@"localhost:1337" options:nil];
    [socket connect]; // this is needed to invoke my "connect" handler - btw, not specified in the example code atm   

    // simple connect and emit back
    [socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {        

        // but emit back with an acknowledgement of receipt
        [socket emitWithAckObjc:@"ackack" withItems:@[@"hello world"]](10, ^(NSArray* data) {
            NSLog(@"Got ack: %@", data);

            // now update my label - but I can't because of a "EXC_BAD_ACCESS" error
            self.mylabel.text = @"self is lost?";
        }); 
    }];
}

I've tried:

  • specifying self as a weakSelf before invoking the socket blocks
  • calling a method instead of writing directly to a ui control
  • setting viewcontroller as strong self in completion callback

None of them seems to work. My node server is working correctly and is not the cause to any of the problems I'm experiencing.

Xcode debugs/breaks to this line in https://github.com/socketio/socket.io-client-swift/blob/master/SwiftIO/SocketAckMap.swift#L36 with the error message:

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7b0b4034)

Do you have any suggestions how to capture self?

Allow . to match any character, including line separators.

First...thank you for this library. I was experiencing an issue in which a large incoming event wasn't being passed to the appropriate on: handler. No error was thrown. After some investigation, I narrowed it down to regex operations that weren't outputting valid json, thus leading the NSJSONSerialization to fail. Here is an example of the regex, although it happens a few times within the library:

var mutMessage = RegexMutable(stringMessage)
let messageGroups = mutMessage["(\\d*)\\/?(\\w*)?,?(\\d*)?(\\[.*\\])?"].groups()

The end of the regex uses a . to match any character, but by default it does not match line separators. If the intent is to include them, SwiftRegex lets us set the option NSRegularExpressionOptions.DotMatchesLineSeparators. I attempted a pull request to do the following but it wasn't working for me:

var mutMessage = RegexMutable(stringMessage)
let messageGroups = mutMessage["(\\d*)\\/?(\\w*)?,?(\\d*)?(\\[.*\\])?",NSRegularExpressionOptions.DotMatchesLineSeparators].groups()

I must be missing something, I thought that subscript would work but it crashes for me. The following did work:

var mutMessage = RegexMutable(stringMessage)
var swiftRegex = SwiftRegex(target: mutMessage, pattern: "(\\d*)\\/?(\\w*)?,?(\\d*)?(.*)?", options: NSRegularExpressionOptions.DotMatchesLineSeparators);
let messageGroups = swiftRegex.groups()

Also, it could be helpful to include a warning when the event parsing fails. Thanks!

SocketEngine.swift:470. EXC_BAD_ACCESS

Hi,

Our app is written in ObjC for iOS 7+, but we are getting this crash:

Thread : Crashed: engineHandleQueue
0 libswiftCore.dylib 0x000000010131d814 swift_unknownRetainUnowned + 40
1 DevAuctionataLive 0x00000001000b86f4 DevAuctionataLive.SocketEngine.(parseEngineMessage in _4DCD037EFB1C27BE04F82A88FF07B400) (DevAuctionataLive.SocketEngine)(Swift.String) -> () (SocketEngine.swift:470)
2 DevAuctionataLive 0x00000001000b86f4 DevAuctionataLive.SocketEngine.(parseEngineMessage in _4DCD037EFB1C27BE04F82A88FF07B400) (DevAuctionataLive.SocketEngine)(Swift.String) -> () (SocketEngine.swift:470)
3 DevAuctionataLive 0x00000001000bb744 protocol witness for DevAuctionataLive.WebSocketDelegate.websocketDidReceiveMessage (DevAuctionataLive.WebSocketDelegate.Self)(DevAuctionataLive.WebSocket, text : Swift.String) -> () in conformance DevAuctionataLive.SocketEngine : DevAuctionataLive.WebSocketDelegate (SocketEngine.swift:605)
4 DevAuctionataLive 0x000000010010df60 DevAuctionataLive.WebSocket.((processResponse in _8EBB333CEB46C95CC2731D7C6BDBCF21) (DevAuctionataLive.WebSocket) -> (DevAuctionataLive.WebSocket.WSResponse) -> Swift.Bool).(closure #1) (WebSocket.swift:602)
5 libdispatch.dylib 0x0000000198959994 _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x0000000198959954 _dispatch_client_callout + 16
7 libdispatch.dylib 0x00000001989640a4 _dispatch_queue_drain + 1448
8 libdispatch.dylib 0x000000019895ca5c _dispatch_queue_invoke + 132
9 libdispatch.dylib 0x0000000198966318 _dispatch_root_queue_drain + 720
10 libdispatch.dylib 0x0000000198967c4c _dispatch_worker_thread3 + 108
11 libsystem_pthread.dylib 0x0000000198b3922c _pthread_wqthread + 816

Namespace use

Hi all,

Could someone please give me an working example that uses namespace in Swift? I try it but not working. Thanks

namespace(nsp) format is wrong

Thank you all guys contributed this awesome project. but there is some thing seems not right.

we should send namespace like this: 0/chat
but in joinNamespace() self.engine?.send("0/\(self.nsp!)")
and it will be 0//chat, the server will complain it.

NSCFArray and NSCFDictionary ?

the data that i become from the parser are always of type NSCFArray and NSCFDictionary. It's not easy to modify the content of this classes.

my Question is: why you use NSJSONReadingOptions.AllowFragments?

with NSJSONReadingOptions.MutableContainers it works like a charm ... i get then NSArrayM and NSDictionaryM

/************ class SocketParser *********/

// Parses data for events
static func parseData(data:String) -> AnyObject? {
var err:NSError?
let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!,
options: NSJSONReadingOptions.AllowFragments, error: &err)
}

Objective-C support

It is not possible to instantiate an IO-Client in an Objective-C class and pass it to child Swift classes (for example: ViewController passes the an central IO-Client to model classes) because of missing @objc in the IO-Client implementation.

emit error event when the socket is denied by the server.

We have server side authentication on socket.io. Incase the server rejects the connection, socket.io client should receive error event or some other event to handle that.

Currently it's not handling this case and the app crashes everytime the socket is denied.

Carthage building error on 955ad84

After fetching the latest commit (955ad84) from carthage branch, got this building error:
error: no such file or directory: '/SomeProject/Carthage/Checkouts/socket.io-client-swift/SocketIOClientSwift/SocketAckMap.swift'

WebSocket.swift:283. EXC_BAD_ACCESS KERN_INVALID_ADDRESS (Crashed: engineHandleQueue)

Hi,

Our app is written in ObjC for iOS 7+, but we are getting this crash. This crash appears in a different place then previously reported:

Thread : Crashed: engineHandleQueue
0 libswiftCore.dylib 0x00000001012b24e8 swift_getObjectType + 24
1 DevAuctionataLive 0x00000001000b1748 DevAuctionataLive.WebSocket.((disconnectStream in _8EBB333CEB46C95CC2731D7C6BDBCF21) (DevAuctionataLive.WebSocket) -> (Swift.Optional<ObjectiveC.NSError>) -> ()).(closure #1) (WebSocket.swift:283)
2 DevAuctionataLive 0x00000001000b1748 DevAuctionataLive.WebSocket.((disconnectStream in _8EBB333CEB46C95CC2731D7C6BDBCF21) (DevAuctionataLive.WebSocket) -> (Swift.Optional<ObjectiveC.NSError>) -> ()).(closure #1) (WebSocket.swift:283)
3 libdispatch.dylib 0x00000001968bd3ac _dispatch_call_block_and_release + 24
4 libdispatch.dylib 0x00000001968bd36c _dispatch_client_callout + 16
5 libdispatch.dylib 0x00000001968c74c0 _dispatch_queue_drain + 1216
6 libdispatch.dylib 0x00000001968c0474 _dispatch_queue_invoke + 132
7 libdispatch.dylib 0x00000001968c9224 _dispatch_root_queue_drain + 664
8 libdispatch.dylib 0x00000001968ca75c _dispatch_worker_thread3 + 108
9 libsystem_pthread.dylib 0x0000000196a992e4 _pthread_wqthread + 816

doPoll: Assertion Failed

After about 2 mins of connection, the pollingDidFail() method auto attempts to reconnect on what looks like a dropped connection. This breaks the assertion below.

Line 272 of SocketEngine.swift
if self.waitingForPost || self.waitingForPoll || self.websocket || self.connected {
assert(false, "We're in a bad state, this shouldn't happen.")
}

I'm currently not doing anything besides connecting and listening for events. When my application is left open for about a minute, this assertion fails. From what I understand, the doPoll() method is eventually triggering the pollingDidFail() method, which only will be called on a dropped connection.

Any thoughts?

forceWebsockets and cookies

Hello,
first of all, thank you for sharing this work, it is very useful.
I'm working on a iOs app that integrate socket.ios, i need to send cookies also when forceWebsockets is setted to true.
It seems like WebSocket doesn't sends cookies with the request also if SocketIOClient has cookies.

My app instantiate SocketIOClient in this way:
self.socket = SocketIOClient(socketURL: endpoint, options: ["forceWebsockets" : true, "cookies" : cookiesToSet])
but the server doesn't receive any cookies.
I've solved this issue by adding manually the cookies header in WebSocket (createHTTPRequest) .
Are there another way to accomplish this?
It is a right to send cookies using WebSocket transport?

How to get parameters of connection event?

On app

socket.connectWithParams(["token": "ABAE1W14YUEYT"])

My question is how to get parameters on server

io.on('connection', function (socket) {
  console.log('connection param: ' + socket.handshake.query.token);
});

Is it right?

Swift Compiler error

After I added the swift1.2 version there are still one error and one warning

/Users/Chris/Documents/Development/Xcode/SIOSwift2/SIOSwift2/SwiftIO/SocketPacket.swift:205:21: error: 'NSMutableArray' is not implicitly convertible to '[AnyObject]'; did you mean to use 'as' to explicitly convert?
self.data = newArr
^
as [AnyObject]
/Users/Chris/Documents/Development/Xcode/SIOSwift2/SIOSwift2/SwiftIO/SwiftRegex.swift:141:28: warning: closure parameter prior to parameters with default arguments will not be treated as a trailing closure
func substituteMatches(substitution: (NSTextCheckingResult, UnsafeMutablePointer) -> String,

Not sure if this is caused by my library error ?

Event not called after connecting to socket

In my case, socket is connected successfully, but after connecting other event are not calling.
The socket is remain connecting, server send event message, but on client side, event method not called. The server run perfectly in android, but issue in iOS. Below is my connection call code.
After connecting, @"connect" is emitted, but after that @"auth_success" is not emitted.

NSString *url = [NSString stringWithFormat:@"%@",SOCKET_URL];

NSMutableDictionary *parameter = [[NSMutableDictionary alloc] init];
[parameter setObject:[NSNumber numberWithBool:YES] forKey:@"reconnects"];
[parameter setObject:@"nameSpace" forKey:@"nsp"];
NSDictionary *params = [NSDictionary dictionaryWithDictionary: parameter];

self.socket = [[SocketIOClient alloc] initWithSocketURL:url options:params];

[self.socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
    NSLog(@"connected successfully");
}];

[self.socket on: @"disconnect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
    NSLog(@"disconnected successfully");
}];

[self.socket on: @"auth_success" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"Auth successfull");
}];

[self.socket onAny:^(SocketAnyEvent *event) {
NSLog(@"Test");
}];

[self.socket on: @"error" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
    NSLog(@"error")
}];

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:[[NSUserDefaults standardUserDefaults] objectForKey:TOKEN] forKey:@"authToken"];
[dictionary setObject:[[NSUserDefaults standardUserDefaults] objectForKey:DOMAIN] forKey:DOMAIN];

NSDictionary *dictionaryForParameter = [NSDictionary dictionaryWithDictionary: dictionary];
[self.socket connectWithParams: dictionaryForParameter];

Can anyone help me to figure out what is wrong in my code? Thanks.

Use of subscripts causes Xcode builds to fail

When importing the Socket_IO_Client_Swift library, and having code like below, Xcode 6.2 will not be able to compile the project.

import Socket_IO_Client_Swift

class Test {
    func causesSegmentationFaultOnCompile() {
        let array = NSArray()
        for item in array {
            let breaks = item["name"] // This line causes the compile failure
            let fine = item.valueForKey("name") // This works fine
        }
    }
}

Attempting to build this results in: "Swift Compiler Error: Command failed due to signal: Segmentation fault: 11"

The stack dump from Xcode is like so:

0.  Program arguments: ... 
1.  While type-checking 'causesSegmentationFaultOnCompile' at /Test.swift:5:5
2.  While type-checking declaration at /Test.swift:8:13
3.  While type-checking expression at [/Test.swift:8:26 - line:8:37] RangeText="item["name"]"

This happens in 1.5.2 and 1.1.2. I used a Podfile, like so:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'Socket.IO-Client-Swift', '1.5.2'

on @"connect" is not emitted

Hello,
When I'm using SocketIO with Objective-C the "connected" NSLog does not appear.

Here is my code:

    self.socket = [[SocketIOClient alloc] initWithSocketURL:@"http://10.211.55.3"
                                                    options:nil
                                   /* options:@{
                                        @"reconnects": @true, // Default is true
                                        @"reconnectAttempts": @5, // Default is -1 (infinite tries)
                                        @"reconnectWait": @5, // Default is 10
                                        @"nsp": @"/socket.io/", // connects to the specified namespace. Default is /
    }*/];

    [self.socket onAny:^{
        NSLog(@"Test");
    }];

    [self.socket on: @"reconnect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"reconnect");
    }];

    [self.socket on: @"connect" callback: ^(NSArray* data, void (^ack)(NSArray*)) {
        NSLog(@"connected");
//        [self.socket emitObjc:@"echo" withItems:@[@"echo test"]];
//        [[self.socket emitWithAckObjc:@"ackack" withItems:@[@"test"]] onAck:0 withCallback:^(NSArray* data) {
//            NSLog(@"Got data");
//        }];
    }];

    // Connect ?
    [self.socket connect];

In Debug navigator I noticed that socket.io was able to contact the server:
screen shot 2015-03-31 at 19 02 51

Can someone help me to figure out what is the problem please? Thanks!

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.