Socket.Io for Swift4 iOS

Socket.io for swift4 ios

socket.io-client-swift

var manager:SocketManager!

var socketIOClient: SocketIOClient!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
ConnectToSocket()
}

func ConnectToSocket() {

manager = SocketManager(socketURL: URL(string: "your url")!, config: [.log(true), .compress])
socketIOClient = manager.defaultSocket

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

socketIOClient.on(clientEvent: .error) { (data, eck) in
print(data)
print("socket error")
}

socketIOClient.on(clientEvent: .disconnect) { (data, eck) in
print(data)
print("socket disconnect")
}

socketIOClient.on(clientEvent: SocketClientEvent.reconnect) { (data, eck) in
print(data)
print("socket reconnect")
}

socketIOClient.connect()
}

Update

In your case: SocketManager: Manager is being released

Sockets created through the manager are retained by the manager. So at the very least, a single strong reference to the manager must be maintained to keep sockets alive.

["Got unknown error from server Welcome to socket.io."]

  1. Check socket.io version on both server and client side, mismatch of both may be cause of this error
  2. Add an "App Transport Security Settings" key in info.plist (Dictionary type) and sub key "Allow Arbitrary Loads" (boolean type) with YES value.

How to emit an event in Socket.io Swift4

Sockets require a connection before emit is called. For this purpose Socket.IO has a listener socket.on ("connect"). So after we got status connected we can emit.

socket.on("connect") { _, _ in
print("socket connected")
socket.emit("your_event", jsonObject)
}

How to connect Socket in Swift 4

You should make a shared property in your SocketIOManager class like this:

static let shared = SocketIOManager()

and then create init() like this:

    var socket: SocketIOClient!

// defaultNamespaceSocket and swiftSocket both share a single connection to the server
let manager = SocketManager(socketURL: URL(string: "http://localhost:3000")!, config: [.log(true), .compress])

override init() {
super.init()

socket = manager.defaultSocket
}

and finally write your methods like this:

func connectSocket() {
let token = UserDefaults.standard.getAccessToken()

self.manager.config = SocketIOClientConfiguration(
arrayLiteral: .connectParams(["token": token]), .secure(true)
)
socket.connect()
}

func receiveMsg() {
socket.on("new message here") { (dataArray, ack) in

print(dataArray.count)

}
}

and call your method like this:

SocketIOManager.shared.connectSocket()

The point is that you should make a strong reference to manager property in your viewController and static let shared = SocketIOManager() you do this for you!

How to connect with Socket.io? Swift 4

It looks like you set the token in wrong place. According to the issue, token should be set as header parameter in configuration:

manager.config = SocketIOClientConfiguration(
arrayLiteral: .compress, .connectParams(["Authorization": token])
)

Try to manage your token this way.

Implement socket.io-client in swift

I have created a Global for socket Class

import SocketIO

class SocketHelper {

static let shared = SocketHelper()
var socket: SocketIOClient!

let manager = SocketManager(socketURL: URL(string: AppUrls.socketURL)!, config: [.log(true), .compress])

private init() {
socket = manager.defaultSocket
}

func connectSocket(completion: @escaping(Bool) -> () ) {
disconnectSocket()
socket.on(clientEvent: .connect) {[weak self] (data, ack) in
print("socket connected")
self?.socket.removeAllHandlers()
completion(true)
}
socket.connect()
}

func disconnectSocket() {
socket.removeAllHandlers()
socket.disconnect()
print("socket Disconnected")
}

func checkConnection() -> Bool {
if socket.manager?.status == .connected {
return true
}
return false

}

enum Events {

case search

var emitterName: String {
switch self {
case .searchTags:
return "emt_search_tags"
}
}

var listnerName: String {
switch self {
case .search:
return "filtered_tags"
}
}

func emit(params: [String : Any]) {
SocketHelper.shared.socket.emit(emitterName, params)
}

func listen(completion: @escaping (Any) -> Void) {
SocketHelper.shared.socket.on(listnerName) { (response, emitter) in
completion(response)
}
}

func off() {
SocketHelper.shared.socket.off(listnerName)
}
}
}

How to use

Connect Socket using this code

SocketHelper.shared.connectSocket { (success) in

}

Start Listen event

SocketHelper.Events.search.listen { [weak self] (result) in
// print(result[0])
}

Emit Event

SocketHelper.Events.search.emit(params: <--Your Params-->)

how to make a basic swift 4 socket io app

Firstly, as the error says, you can't use manager instance property outside of viewDidLoadto initiate socket, if you want to access a variable in any method you must declare it global so its scope is the entire class. This code does with socket variable:

var socket:SocketIOClient!

override func viewDidLoad() {
super.viewDidLoad()

let manager = SocketManager(socketURL: URL(string: "http://localhost:3000/chat.html?name=developer&room=test")!, config: [.log(true), .compress])

self.socket = manager.defaultSocket

self.socket.connect()

newMessageSubmit.addTarget(self, action: #selector(sendNewMessage), for: .touchUpInside)
}

@objc func sendNewMessage() {

let newMessageContent = newMessageInput.text!

print("Sending message..." + newMessageContent)

self.socket.emit("createMessage", newMessageContent)

}

connect socketIO with options in swift

I figured out the solution.
The way to include options has been revised in the latest version.
I did the following and it worked:-

manager  = SocketManager(socketURL:  URL(string:"myurl:123")!, config: [.log(true), .forceNew(true), .reconnectAttempts(10), .reconnectWait(6000), .connectParams(["key":"value"]), .forceWebsockets(true), .compress])
socket = manager?.defaultSocket

Losing reference to variable while using SocketIO in swift 4

I don't think you should declare your variable in the AppDelegate.

I am using Socket.IO too in one of my app and I prefer use it from a shared instance class. I don't know if you are familar with it, but it is a common architecture in iOS development.

It is based on a singleton instance and allows you to keep instance of variables in memory during all the life of the app.

For you case, you can do the following for example:

private let _managerSharedInstance = Manager()

class Manager() {

private var connectionManager = SocketManager(socketURL: URL(string: "http://0.0.0.0:8080")!)
private var usersName = ""
private var socket:SocketIOClient!

var delegate: UIViewController?

class var shared: Manager {
return _managerSharedInstance
}

init() {
connectionManager.reconnects = true
socket = connectionManager.defaultSocket;
setSocketEvents();
socket.connect();
}

private func setSocketEvents() {
// Your socket events logic
}

func attemptToIdentify(user username: String) {
socket.emit("identify", ["username": username])
}

func attemptToSend(message: String) {
socket.emit("message", ["username": username, "message": message])
}

}

So, in your AppDelegate.didFinishLaunchingWithOptions, you can now call:

Manager.shared.attemptToIdentify(user: username)

You can call this from everywhere in your code, the shared class variable will return the instance of _managerSharedInstance.

By the way, you should set your delegate of the controller in the viewWillAppear of that controller and not in the AppDelegate.

func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
Manager.shared.delegate = self
}

Socket.io with Swift is not handshaking

It could be related to security.
Typically ios apps expect connections using https. To allow http connections, in your
info.plist add this (temporary security fix):

<key>NSAppTransportSecurity</key>
<dict>

<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>


Related Topics



Leave a reply



Submit