ios - applicationDidBecomeActive 在 ViewController 加载后运行

标签 ios swift socket.io

我正在使用 socket.io 来使用实时机制。我现在面临的问题是 Socket.io 的对象是在加载 viewController 之后创建的

我正在使用单例设计

import SocketIO

class SocketIOManager: NSObject {

    static let sharedInstance = SocketIOManager()

    var socket: SocketIOClient!

    func establishConnection() {
       socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
       socket.connect()

    }

    func closeConnection() {
        socket.disconnect()
    }

}

无论如何,我都需要在 establishConnection 中设置套接字,以确保用户已经与 token 一起建立了与服务器的连接。如果我按照 Vlad 的回答进行操作,连接将永远无法建立,因为 token 之前是空的,因此用户将无法连接。

用户登录

func logIn() {
   // Getting it from alamofire
   keychain["token"] = token
   //then only establish connection
   SocketIOManager.sharedInstance.establishConnection()
}

如果我使用 Init 方法,那么 socket 将为 nil,因为在 applicationDidBecomeActive 中有 SocketIOManager.sharedInstance.establishConnection(),所以逻辑是,每当用户加载应用程序时,applicationDidBecomeActive 就会运行

所以从技术上讲,我正在使用 sharedInstance 来运行 socket.io 对象。

func applicationDidBecomeActive(_ application: UIApplication) {
        SocketIOManager.sharedInstance.establishConnection()
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

现在 didBecomeActive 中的套接字对象在 View 加载后运行

override func viewDidLoad() {
    super.viewDidLoad()
    listeningOnMerchant()

}

func listeningOnMerchant() {
   // I got error around here
   SocketIOManager.sharedInstance.socket.on("listening") { ack, data in
      print("something")


   }
  }
}

这会崩溃,因为 socket 是 nil。如何使 viewController 不崩溃。我可以使用 let 方法来停止崩溃

if let socket = SocketIOManager.sharedInstance.socket {

}

但如果我使用 socket 并且套接字将不会运行,它将为零。如何让套接字不崩溃?

因为我确实需要将 socket.connect 放在 applicationDidBecomeActive 上以使其与连接与 didLaunch

保持一致

谢谢!

最佳答案

从技术上讲,要解决此问题,您需要使用 init 方法,这样套接字就不会为 nil。由于您需要在应用程序暂停等情况下运行套接字,因此无论如何都需要使用 init 方法。

   private override init() {
        self.socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(true), .compress, .forceNew(true), .connectParams(["token": getToken()])])
        super.init()
    }

添加forceNew(true) 这样您就不会为一个用户创建多个连接

下一步您需要做的是创建另一个只有您的 loginViewController 可以访问的函数

 func establishConnectionWhenLogin(_ token: String) {
        self.socket =  SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": token])])
        socket.connect()

    }

将 token 传递给参数,以便只有用户登录后您才想建立连接。如果您有任何问题,请告诉我

我将这个解决方案用于我自己的应用程序并且它运行良好

关于ios - applicationDidBecomeActive 在 ViewController 加载后运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47328573/

相关文章:

ios - 我如何应用 CICrystallize 过滤器 iOS 7?

swift - NSInternalInconsistencyException _variable 不是 projectName.Classname 的属性

node.js - 测试套接字是否打开并正在监听,node,socket.io

swift - 相机输入的尺寸为一像素一像素

node.js - 在node.js中使用npm后从客户端访问underscore.js

ruby-on-rails-3 - 直接从 Rails 应用程序向 Node.js 和 Socket.io 推送服务器发送消息

ios - 从 Form/NavigationView 中的闭包引用属性并交换 View 时,SwiftUI 内存泄漏

ios - UIImage 在模拟器上工作,但在设备上 swift 崩溃

ios - 如何在 IOS Swift 中捕获页面滑动事件

ios - Swift 2.2 - ViewController 类型的值没有成员操作