2016-01-31 40 views
0

按照標題,我在處理socket.io時遇到了一些問題。它在第一個視圖控制器中連接得非常好,因此在第二個控制器中發生奇怪的事情。Swift中來自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() 
} 

} 

您可能已經注意到,在第一視圖控制器,當viewDidAppear()如果用戶登錄時啓動,應用程序會檢查或不。如果有人已經登錄,那很好。如果沒有人登錄,它將執行一個循環(模式繼續)到秒視圖控制器

登錄表單將顯示在第二個視圖控制器中,一旦用戶點擊登錄按鈕,你可能想看看代碼

讓我們假設一切正常,直到涉及到importData(),該函數根本沒有啓動,但應用程序剛剛啓動,爲什麼?

下面是控制檯的屏幕截圖,請注意「您是否導入?」,如果啓動該功能,應用程序應從第一個視圖控制器返回一些附加消息。

Screenshot

回答

0

掙扎了幾天後,我想我可能已經找到了正確的答案。

最後,我所定義2個不同的插座連接的處理程序這樣:兩個視圖控制器

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

如果有一個結論,我可以從這個難題中得出結論,我們不能使用單個套接字處理程序來處理來自不同視圖控制器的套接字方法。