how to use socket io in swift - ios

Error :
Blockquote
it says "Argument labels '(String:)' do not match any available overloads"
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let socket = SocketIOClient(manager: URL(String:"http://localhost:8080") as! URL, nsp: [.log(true), .forcePolling(true)])
// let socket = SocketIOClient(manager: URL(string: "http://localhost:8080")! as! SocketManagerSpec, nsp: [.log(true), .forcePolling(true)])
override init() {
super.init()
socket.on("test") { dataArray, ack in
print(dataArray)
}
}
How can I solve this.
any help would be apprciated.

I'd recommend you to read through the Socket IO documentation before trying to implement it. To get you started, you need to have a socketClient property in your Socket Manager class and you need to instantiate SocketClient before using Socket events.
class SocketManager {
//Socket IO client instance to emit and observe events of your socket
private let socketClient: SocketIOClient!
private init() {
let socketUrl = "Your Socket URL here"
socketClient = SocketIOClient(socketURL: URL(string: socketURL)!)
setupEvents()
}
func setupEvents() {
socket.on("test") { dataArray, ack in
print(dataArray)
}
}
Hope this helps you get started

I'd recommended below coding:
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
socket.emit("update", ["amount": cur + 2.50])
}
ack.with("Got your currentAmount", "dude")
}
socket.connect()

Related

URLSEssion Does not send any response

I was trying to learn the basics of networking with openweather api.
Implemented a very basic struct like this.
protocol WeatherManagerDelegate {
func didUpdateWeather(_ weatherManager : WeatherManager, weather : WeatherModel)
func didFailWithError(error: Error)
}
struct WeatherManager {
var delegate : WeatherManagerDelegate?
var temp : Double = 0.0
let weatherURL = "https://api.openweathermap.org/data/2.5/weather?appid=40ca58efce193db0fc801564afb08283&units=metric"
func fetchWheather(cityName : String){
let urlString = "\(weatherURL)&q=\(cityName)"
performRequest(with: urlString)
}
func performRequest(with urlString: String){
if let url = URL(string: urlString){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url){ (data, response, error) in
if error != nil{
delegate?.didFailWithError(error: error!)
return
}
if let safedata = data {
if let weather = self.parseJSON(weatherData: safedata){
// let WeatherVC = WeatherViewController()
self.delegate!.didUpdateWeather(self, weather: weather)
}
print("Data is \(safedata)")
}
}
task.resume()
}
}
func parseJSON(weatherData:Data)-> WeatherModel?{
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
let id = decodedData.weather[0].id
let temp = decodedData.main.temp
let name = decodedData.name
let weather = WeatherModel(conditionID: id, cityName: name, temperature: temp)
return weather
} catch{
print("error is \(error)")
delegate?.didFailWithError(error: error)
return nil
}
}
}
But the issue is none of the print statements inside the requests are giving any outputs , nor i am able to update the UI. But the URL is giving the correct JSON Response when tried in browser
I am using the latest XCode on iOS 15 (iPhone 11 Device) with M1 Pro chip mac.
Found some threads which mentions to use "open with rosetta" but none of which worked.
also, not getting any errors on the console
Any solution?
Edit : Called in VC like this:
func textFieldDidEndEditing(_ textField: UITextField) {
if let city = searchTextField.text {
weatherManager.fetchWeather(cityName: city)
}
searchTextField.text = ""
}
Please try using:
let session = URLSession.shared
…instead of creating local session variable within the function scope
And if error != nil then don't return from that block. Simply use if-else for error handling.

How to perform UI actions from Socket.io On Function

I am new to using socket.io. I have made a singleton class for socket works and I am using an Instance of it in my app.
My question is: How to perform any action after receiving the data in the On function when I am on a different view controller?
import Foundation
import SocketIO
import UIKit
protocol testUI {
func fareUpdate(amount:NSNumber)
}
var delegate:testUI?
class SocketHelper {
static let shared = SocketHelper()
var socket: SocketIOClient!
let manager = SocketManager(socketURL: URL(string: "http://13.59.81.136:3355/")!, config: [.log(true), .compress, .connectParams(["token":user.shared.token])] )
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 testStatus(){
print(socket.status)
}
func checkConnection() -> Bool {
if socket.manager?.status == .connected {
return true
}
return false
}
enum Events {
case search
func getFareEstimate(params:NSDictionary){
SocketHelper.shared.socket.emit("fareEstimate" , params)
}
func listen(completion: #escaping (Any) -> Void) {
SocketHelper.shared.socket!.on("rideFares") { (response, emitter) in
print(response)
let dic = response as! NSArray
let data = dic[0] as! NSDictionary
let fare = data["fare"] as! NSNumber
DispatchQueue.main.async {
delegate?.fareUpdate(amount: fare)
}
}
// func off() {
// SocketHelper.shared.socket.off(listnerName)
// }
}
}
}
I have tried using a delegate but it doesn't seem to work. I could be on multiple view controllers when the socket receives the data in the On function.

connect socketIO with options in swift

I am trying to use socketIO for one of my projects.
I need to use following options while connecting to my socketIO server.
let socketConfig = SocketIOClientOption.self
socketConfig.forceNew(true)
socketConfig.reconnects(true)
socketConfig.reconnectAttempts(10)
socketConfig.reconnectWait(6000)
According to socketIO docs (https://github.com/socketio/socket.io-client-swift) I am not able to find a way to pass SocketIOOptions while connecting.
I have been trying to use below code to connect but it fails due to the absence of these options
let manager = SocketManager(socketURL: URL(string: "myurl:9476")!, config: [.log(true), .connectParams(["key":"value"])])
let socket = manager.defaultSocket
SocketIO version used:- 'Socket.IO-Client-Swift', '~> 13.3.0'
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
Socket singleton class in Swift 4
import Foundation
import UIKit
import SwiftyJSON
import Alamofire
import SocketIO
import ObjectMapper
typealias OrderEventResponseBlock = (_ response : Any? , _ type : OrderEventType) -> ()
typealias TrackResponseBlock = (_ response : Any?) -> ()
class SocketIOManager: NSObject {
static let shared = SocketIOManager()
private var manager: SocketManager?
var socket: SocketIOClient?
override init() {
super.init()
let token = UDSingleton.shared.userData?.userDetails?.accessToken
guard let URL = URL(string: APIBasePath.basePath) else {return}
manager = SocketManager(socketURL: URL , config: [.log(true), .connectParams(["access_token" : /token])])
socket = manager?.defaultSocket
setupListeners()
}
//Server Methods
func establishConnection() {
let token = UDSingleton.shared.userData?.userDetails?.accessToken
if (self.socket?.status == .disconnected || self.socket?.status == .notConnected ) {
if (token != nil || token != "") {
socket?.connect()
}
}
else {
debugPrint("======= Socket already connected =======")
}
}
func closeConnection() {
debugPrint("=======***** SocketClientEvent.disconnect called ****=======")
socket?.disconnect()
}
func setupListeners() {
socket?.on(SocketClientEvent.disconnect.rawValue) { [weak self] (array, emitter) in
debugPrint("======= SocketClientEvent.disconnect listener=======")
self?.establishConnection()
}
socket?.on(SocketClientEvent.error.rawValue) {[weak self] (array, emitter) in
debugPrint("======= SocketClientEvent.error =======")
self?.establishConnection()
}
socket?.on(SocketClientEvent.connect.rawValue) { (array, emitter) in
if self.socket?.status == .connected {
debugPrint("======= userauth after connected =======")
}
}
}
func getStatus() -> SocketIOStatus? {
guard let status = self.socket?.status else{ return nil }
return status
}
//MARK:- Listening Events
//MARK:-
func listenOrderEventConnected(_ completionHandler: #escaping OrderEventResponseBlock) {
socket?.on(SocketEvents.OrderEvent.rawValue) {(arrData, socketAck) in
guard let item = JSON(arrData[0]).dictionaryObject else {return}
guard let type = item["type"] as? String else{return}
guard let typeSocket : OrderEventType = OrderEventType(rawValue: type) else {return}
}
}
//MARK:- EmitterWithAcknowledge Events
func emitMapLocation(_ userData : [String: Any] , _ completionHandler: #escaping TrackResponseBlock) {
socket?.emitWithAck(SocketEvents.CommonEvent.rawValue , userData).timingOut(after: 4.0, callback: { (response) in
guard let item = JSON(response[0]).dictionaryObject else{return}
let json = JSON(item)
if json[APIConstants.statusCode.rawValue].stringValue == Validate.successCode.rawValue {
let objDriver = Mapper<ApiSucessData<DriverList>>().map(JSONObject: item)
completionHandler( objDriver?.object)
}
})
}
func getParticularOrder(_ userData : [String: Any] , _ completionHandler: #escaping TrackResponseBlock) {
socket?.emitWithAck(SocketEvents.CommonEvent.rawValue, userData).timingOut(after: 2.0, callback: { (response) in
let item = JSON(response[0]).dictionaryObject
let json = JSON(item)
if json[APIConstants.statusCode.rawValue].stringValue == Validate.successCode.rawValue {
let objOrder = Mapper<ApiSucessData<Order>>().map(JSONObject: item)
completionHandler( objOrder?.object)
}
})
}
}

Socket.io Swift client handler doesn't trigger

I have issue with soket.io client, and as I read here, you should define socket manager as a global variable so it's not released by ARC.
My code with that in mind:
let manager = SocketManager(socketURL: URL(string: Api.SOCKET)!, config: [.log(true), .path(Api.SOCKET_PATH)])
let socket: SocketIOClient?
....
override func viewDidLoad() {
super.viewDidLoad()
subscribeOnTransaction() { }
}
func subscribeOnTransaction() {
if self.socket == nil {
socket = manager.socket(forNamespace: Api.SOCKET_PATH)
subscribeToChangesChannel { }
socket?.on(clientEvent: .connect) { data, ack in
self.socket?.emit("transaction", self.sellOrder.id!)
}
self.socket?.on(clientEvent: .statusChange) {data, ack in
print(data)
}
self.socket?.connect()
}
}
func subscribeToChangesChannel(completion: #escaping () -> Void) {
if let socket = self.socket {
socket.on("transaction/\(self.sellOrder.id!)") { data, ack in
print(data, ack)
if data.count > 0 {
let rawResult = data[0]
if let result = rawResult as? [String: Any] {
let newRawValue = result["new_val"]
if let transaction = self.parseSocketResponse(newRawValue) {
self.openTransactionTrackingScreen(transaction)
completion()
}
}
}
}
}
}
But it doesn't call the handlers when I set breakpoints. Connection is established, everything's fine, with log turned on I get
Got polling response
LOG SocketEnginePolling: Got poll message:
What might be the problem? Any ideas? Will appreciate any help, thanks

How to use Namespace in SocketIOClient in swift

I am using latest version of SocketIOClient (13.1.1). How to emit or listen using namespace.
This should be enough :
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let manager = SocketManager(socketURL: URL(string: "")!, config: [.log(false), .compress, .forcePolling(false)])
var avaialableCallBack:(([Any]) -> Void)?
override init(){
super.init()
}
func establishConnection() {
let socket = manager.socket(forNamespace: "/consumer")
socket.on("connect") { (data, ack) -> Void in
print("socket connected",data,ack)
}
socket.on(clientEvent: .disconnect){data, ack in
print("socket disconnected")
}
socket.on("session-available") { (dataArr, ack) -> Void in
ack.with(true)
if let sessionAvailableCB = self.avaialableCallBack {
sessionAvailableCB(dataArr)
}
}
socket.connect()
}
func closeConnection() {
let socket = manager.socket(forNamespace: "/consumer")
socket.disconnect()
}
func emitMessage(message:String,data:[String:Any]){
let socket = manager.socket(forNamespace: "/consumer")
socket.emit(message,data)
}
func emitMessageWithAck(message:String,data:[String:Any]) -> OnAckCallback{
let socket = manager.socket(forNamespace: "/consumer")
return socket.emitWithAck(message, data)
}
}

Resources