在Swift 4中使用SocketIO时丢失对变量的引用

时间:2018-10-19 05:08:16

标签: swift socket.io

我是Swift的新手,在开发iOS时总是有些混乱,请耐心等待。

所以在我的AppDelegate中,我有一个像这样的变量

var manager = Manager()

在我拥有的didFinishLaunchingWithOptions中

let controller = ChatRoomViewController()
self.manager.delegate = controller
self.manager.setup()
self.manager.attemptToIdentify(user:username);

在Manager中,我有

var connectionManager = SocketManager(socketURL: URL(string: "http://0.0.0.0:8080")!)
var usersName = ""
var socket:SocketIOClient! 
func setup(){
    connectionManager.reconnects = true
    socket = connectionManager.defaultSocket;
    self.setSocketEvents();

    socket.connect();
}

这有效,我能够打开一个套接字,该套接字在node.js服务器上显示用户名。现在,当我从主视图导航到聊天控制器并致电

   appDelegate.manager.attemptMessage(msg: message);

控制台告诉我不再连接。据我所知,我正在丢失对其中一个变量的引用。

2 个答案:

答案 0 :(得分:1)

您可以在controller方法中将didFinishLaunchingWithOptions变量的对象设置为经理的代表。但是,当您在用户界面上导航ChatRoomViewController时,会打开另一个ChatRoomViewController对象。

您应在ChatRoomViewController类的viewDidLoad方法中设置经理的委托,像这样

class ChatRoomViewController: UIViewController{

    override func viewDidLoad(){
         super.viewDidLoad()
         appDelegate.manager.delegate = self
    }
}

答案 1 :(得分:1)

我认为您不应该在AppDelegate中声明变量。

我也正在我的一个应用程序中使用Socket.IO,我更喜欢从共享实例类中使用它。我不知道您是否熟悉它,但这是iOS开发中的常见体系结构。

它基于单例实例,允许您在应用程序的整个生命周期中将变量的实例保留在内存中。

根据您的情况,您可以执行以下操作:

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])
    }

}

因此,您现在可以在AppDelegate.didFinishLaunchingWithOptions中致电:

Manager.shared.attemptToIdentify(user: username)

您可以在代码中的任何地方调用它,shared类变量将返回_managerSharedInstance的实例。

顺便说一句,您应该将控制器的代表设置在该控制器的viewWillAppear中,而不要设置在AppDelegate中。

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