代码之家  ›  专栏  ›  技术社区  ›  J.Doe

套接字中的异常行为。Swift中的io

  •  0
  • J.Doe  · 技术社区  · 8 年前

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

    下面是代码:

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

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

    你可能已经注意到了 第一视图控制器 ,当 视图显示() 启动时,应用程序将检查用户是否登录。如果有人已经登录,那就没事了。如果没有人登录,它将执行segue(模式segue)以 第二视图控制器 .

    登录表单将呈现在第二视图控制器中,并且一旦用户点击登录按钮, 你可能想看看代码 .

    让我们假设一切正常,直到importData(),函数根本没有启动,但应用程序只是继续运行,为什么?

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

    Screenshot

    1 回复  |  直到 8 年前
        1
  •  0
  •   J.Doe    8 年前

    经过几天的挣扎,我想我可能找到了正确的答案。

    最终,我定义了两种不同的套接字处理程序连接:

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

    用于两个视图控制器。

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