Swift中来自socket.io的异常古怪行为 [英] Unexpected quirky behavior from socket.io in Swift

查看:83
本文介绍了Swift中来自socket.io的异常古怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照标题,我在处理socket.io时遇到了一些麻烦.它在第一个视图控制器中的连接非常好,因此在第二个控制器中发生了奇怪的事情.

As per title, I'm having some trouble dealing with socket.io. It connects really well and accordingly in the first view controller but weird things happen when it comes to second controller.

这是代码:

第一个控制器:我已经声明了一些全局变量以用于两个视图控制器之间的连接.

import UIKit
import SocketIOClientSwift
import SwiftyJSON
import CoreData

//declare some global variable
var patientCoreData = [NSManagedObject]()
var numberOfUsersExisting:Int = 0 //assign to 0 by default
var appUserData: Patient? //for specific user
var pSample: Array<Patient> = [] //for all user

//initiate socket globally
let socket = SocketIOClient(socketURL: "localhost:3000", options: [
    "reconnects": true
])

func reportStatus(){
    socket.on("connect") {data, ack in
        print("Report status: View Controller connected")
        socket.emit("click", "Client app connected")
    }
}

func readDataFromSocket(completion: (data:AnyObject)-> ()){
    socket.on("reply") {data, ack in
        print("database replied")
        completion(data: data)
    }//socket
}//readDataFromSOCKET

func importData(){
    reportStatus()
    socket.connect()
    readDataFromSocket(){ data in
        let json = JSON(data)
        let nou = json[0].count
        if nou > 0 {
            print("Test(1st VC): grabbing data from database")
            for var i=0; i<nou; ++i{
                numberOfUsersExisting = nou
                pSample += [Patient(id: json[0][i]["ID"].intValue, name: json[0][i]["Name"].stringValue, gender: json[0][i]["Gender"].stringValue, mileage: json[0][i]["Mileage"].doubleValue)]
            pSample.sortInPlace({$0.globalPatientMileAge < $1.globalPatientMileAge})
        }
        print("Successfully grabbed data")
    }else{
        print("No user in the database")
        numberOfUsersExisting = 0
    }
}//readDataFromSocket
}

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()

}

override func viewDidLoad() {
    super.viewDidLoad()

}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    print("First view appeared")
    let prefs = NSUserDefaults.standardUserDefaults()

    //if an user has logged in
    let isLoggedIn = prefs.integerForKey("ISLOGGEDIN") as Int
    if (isLoggedIn != 1){
        print("No user currently, so heading to login screen")
        socket.disconnect()
        self.performSegueWithIdentifier("gotoLogin", sender: self)
    }else{
        print("ViewDidAppear: An user has been logged in")
        let permissionToLoadData = prefs.integerForKey("ISLOGGEDIN")

        if (permissionToLoadData != 1) {
            print("Please grant permission to get data")
        }else{
            print("First view: connecting to database")

            importData()

        }//permission to load data
    }
}//end of viewDidAppear

}

第二个控制器:

import UIKit
import SocketIOClientSwift
import SwiftyJSON
import CoreData

var nou:Int?

class LoginViewController: UIViewController {
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let registeredUserID = NSUserDefaults.standardUserDefaults().stringForKey("registerPatientID")
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

func displayAlertMessage(userMessage:String){
    let alert = UIAlertController(title: "Alert", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert)
    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)
    alert.addAction(okAction)
    self.presentViewController(alert, animated: true, completion: nil)
}

func successMessage(userMessage:String){
    let alert = UIAlertController(title: "Welcome Back", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert)
    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)
    alert.addAction(okAction)
    self.presentViewController(alert, animated: true, completion: nil)
}

@IBOutlet weak var loginPatientID: UITextField!

@IBAction func LoginButton(sender: AnyObject) {

    let logInUserID = loginPatientID.text
    if (logInUserID!.isEmpty){
        displayAlertMessage("Please enter your Patient ID!")
        return
    }else{
        print("Test: requesting login permission from database")

        socket.emit("loginRequest", logInUserID!)
        print("Test: requested")

        socket.on("loginReply") {data, ack in
            let jsonLogin = JSON(data)
            if jsonLogin[0].intValue == 1{
                print("Test: ID Matched, putting up ViewController")

                self.prefs.setObject(logInUserID, forKey: "AppUserID")
                self.prefs.setInteger(1, forKey: "ISLOGGEDIN")
                self.prefs.synchronize()

                let permissionToLoadData = self.prefs.integerForKey("ISLOGGEDIN")

                if (permissionToLoadData != 1) {
                    print("Please grant permission to get data")
                }else{
                    print("First view: connecting to database")

                    importData()
                    print("Did you import?")

                }//permission to load data

                self.loginPatientID.resignFirstResponder()
                self.dismissViewControllerAnimated(true, completion: nil)
            }else if jsonLogin[0].intValue == 0{
                    self.displayAlertMessage("Sorry, you are not assigned to this program")
            }else if jsonLogin[0].intValue == 3{
                print("Test: Query problem")
            }else{
                print("Test: not getting anything from ID database")
            }
        }//socket.on
    }//else
}//login button


override func viewDidLoad() {
    super.viewDidLoad()
    print("Login View Controller loaded")

}

override func viewDidAppear(animated: Bool) {
    socket.connect()
    print("LoginVC: establishing connection")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.view.endEditing(true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

您可能已经注意到,在第一视图控制器中,当启动 viewDidAppear()时,该应用将检查用户是否登录.如果有人已经登录,就可以了.如果没有人登录,它将对第二个视图控制器执行segue(模态segue).

You may have noticed that in First view controller, when the viewDidAppear() is launched, the app will checks if user is login or not. If somebody has already logged in, it's fine. If there is nobody logging in, it will perform a segue(modally segue) to Second view controller.

登录表单将显示在第二个视图控制器中,一旦用户单击登录按钮,您可能想查看代码.

A login form will be presented in second view controller and once user hits the login button, you might wanna look at the code.

让我们假设一切正常,直到涉及importData()为止,该功能完全没有启动,但应用程序仍在运行,为什么?

Let's assume that everything goes right until it comes to importData(), the function isn't launched at all but the app just goes on, why?

这是控制台的屏幕截图,请注意您导入了吗?",如果启动了该功能,则应用程序应从第一个视图控制器返回一些附加消息.

Here's a screenshot of the console, pay attention to "Did you import?", if the function is launched, the app should return some additional message from 1st view controller.

推荐答案

在奋斗了几天之后,我认为我可能已经找到了正确的答案.

After struggling for a few days, I think I may have found the correct answer.

最终,我这样定义了2个不同的套接字处理程序连接:

Eventually I defined 2 different socket handlers connection as such:

let loginSocket = SocketIOClient(socketURL: "localhost:3000")
let socket = SocketIOClient(socketURL: "localhost:3000", options: [
"reconnects": true
])

用于两个视图控制器.

如果有一个结论,我可以从这个难题中得出结论,那就是我们不能对来自不同视图控制器的套接字方法使用单个套接字处理程序.

If there is a conclusion I can draw from this conundrum is that we can't use single socket handler for socket methods from different view controller.

这篇关于Swift中来自socket.io的异常古怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆