2017-08-16 50 views
0
//Just a struct to save information about the User 
var user = AppUser() 

override func viewDidLoad() { 
    super.viewDidLoad() 

//Verify if user is logged in 
    verifyUser() 
    user.email = "blabla" 

    print("viewdidload user: \(user)") 

} 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(true) 

    print("viewdidappear user: \(user)") 

} 

func verifyUser() { 

    print("verify user called") 

    //Log in verification 
    guard let userID = Auth.auth().currentUser?.uid else { 
     perform(#selector(handleLogOut), with: nil, afterDelay: 0) 

     print("nil user") 

     return 
    } 

    ref.child("users").child(userID).observeSingleEvent(of: .value, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject] { 
      self.user = AppUser(dictionary: dictionary) 

      print(self.user) 
     } 
    }) { (error) in 
     print(error.localizedDescription) 
    } 
} 

控制檯:如何正確讀取viewDidLoad()func上的Firebase數據庫?

verify user called 


viewdidload user: AppUser(id: nil, name: nil, email: 
Optional("blabla"), completedRegister: nil, FULLUser: nil) 


viewdidappear user: AppUser(id: nil, name: nil, email:     
Optional("blabla"), completedRegister: nil, FULLUser: nil) 


AppUser(id: nil, name: nil, email: Optional("[email protected]"),  
completedRegister: Optional(false), FULLUser: Optional(false)) 

的問題很簡單。有人可以解釋在「驗證用戶名」和「用戶」之間打印"print("viewDidLoad user:....")"與數據庫信息的可能性嗎?

問題是,當我嘗試獲取viewDidLoad上的用戶信息由於某種原因,該函數沒有獲取信息,所以值仍然爲零。這是時間問題嗎?

我試圖把一個循環功能verifyUser()之後,但它從來沒有得到

out: 

    while user.email == nil { 
      print("Waiting...") 
     } 

所以......這就是問題

謝謝!

編輯阿納斯·門哈爾 這是我的結構。爲什麼做一個NSObject會更好? 我做了一個結構,因爲我可以做兩inits不同(一個空)和NSObject的沒讓我出於某種原因

struct AppUser { 
var id: String? 
var name: String? 
var email: String? 

var completedRegister: Bool? 

var FULLUser: Bool? 

init(dictionary: [String: Any]) { 
    self.id = dictionary["id"] as? String 
    self.name = dictionary["name"] as? String 
    self.email = dictionary["email"] as? String 

    self.completedRegister = Bool((dictionary["completedRegister"] as? String)!) 

    self.FULLUser = Bool((dictionary["FULLUser"] as? String)!) 

} 
init() { 
    self.id = nil 
    self.name = nil 
    self.email = nil 

    self.completedRegister = nil 

    self.FULLUser = nil 

} 
} 

編輯爲亞太區首席技術官Matt

,如果我打印出來只是在打印字典用戶完成信息的同時。在一切結束。

+0

你有沒有打印'讓字典= snapshot.value'?你可以加這個嗎? – Hitesh

+0

讓我看看你的AppUser模態類,它必須像類一樣用戶:NSObject {var_id:String? var name:String? var email:String? var imageURL:String? }並且也使用這一行 user.setValuesForKeys(dictionary) –

回答

1

問題是viewDidLoad()在打印"viewdidload user: \(user)"之前調用verifyUser()。打印前,verifyUser()中的所有內容都將完成(網絡通話除外)。

所以這裏是事件發生的對你的序列:

  1. super.viewDidLoad()
  2. verifyUser()
  3. 打印語句是verifyUser()
  4. 後衛聲明是verifyUser()
  5. 打印在viewDidLoad()的說明
  6. 每當通話結束 -
  7. 打印在封閉的.observeSingleEventOf內super.viewDidAppear()

一切都將4後發生的一些點。如果您想在通話結束時執行某些操作,請將其置於關閉狀態。

像這樣:

ref.child("users").child(userID).observeSingleEvent(of: .value, with: { (snapshot) in 
    if let dictionary = snapshot.value as? [String: AnyObject] { 
     self.user = AppUser(dictionary: dictionary) 
     //***handle stuff that needs the user here 
     print(self.user) 
    } else { 
     //***handle getting no data for the user or data that is not [String: AnyObject] 
    } 
}) { (error) in 
    //***handle any errors here 
    print(error.localizedDescription) 
} 

,我添加了註釋是請求完成時將可能被稱爲地方的地方。

附註:如果你要使用APPUSER一個結構,只是確保你知道結構和類之間的差異。你可以有一個名爲APPUSER類,有兩個不同的inits這樣的:

class AppUser { 
    var id: String? 
    var name: String? 
    var email: String? 
    var completedRegister: Bool? 
    var FULLUser: Bool? 

    ///initialization from a dictionary 
    init(dictionary: [String: Any]) { 
     id = dictionary["id"] as? String 
     name = dictionary["name"] as? String 
     email = dictionary["email"] as? String 

     if let completed = dictionary["completedRegister"] as? String { 
      if completed == "true" { 
       completedRegister = true 
      } else if completed == "false" { 
       completedRegister = false 
      } 
     } 

     if let fullUser = dictionary["FULLUser"] as? String { 
      if fullUser == "true" { 
       FULLUser = true 
      } else if fullUser == "false" { 
       FULLUser = false 
      } 
     } 
    } 

    ///initialization without a dictionary 
    init() { 
     //dont need to set any variables because they are optional 
    } 
} 

let user1 = AppUser(dictionary: ["id": "12342", 
          "name": "John Doe", 
          "email": "[email protected]", 
          "completedRegister": "true", 
          "FULLUser": "true"]) 
    ///user1 properties: 
    id: Optional("12342") 
    - some: "12342" 
    name: Optional("John Doe") 
    - some: "John Doe" 
    email: Optional("[email protected]") 
    - some: "[email protected]" 
    completedRegister: Optional(true) 
    - some: true 
    FULLUser: Optional(true) 
    - some: true 

let user2 = AppUser() 
///user2 properties: none 
+0

哪個是類的優點?是不是結構是值類型和類是引用類型的主要區別?所以在我的情況下,結構會更好地完成這項工作嗎?最後一件事,爲什麼網絡內容會在viewDidLoad代碼的其餘部分之後出現?謝謝!! – Alexis

+0

是的。隨着功能的擴展,類作爲引用類型使得它們稍後更具動態性。網絡通話按您寫入的順序開始,但不一定按照該順序完成。想象一下,你正在下載一張10MB的高分辨率照片和500kb的低分辨率照片。您可以按任意順序啓動它們,但(除非它們同步運行)500kb可能會先完成。 – erdos