//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)
}
}
Console:
安慰:
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("x@gmail.com"),
completedRegister: Optional(false), FULLUser: Optional(false))
The question is simple. Can someone explain how is it possible that "print("viewDidLoad user:....")"
is printed between "verify user called" and "the user" with the database information?
问题很简单。有人可以解释一下“打印(”viewDidLoad user:....“)”是如何在“验证用户调用”和“用户”之间打印数据库信息的?
The problem is when I try to get information of the user on the viewDidLoad the function for some reason hasn't get the information so the values are still nil. Is it a question of time?
问题是当我尝试在viewDidLoad上获取用户的信息时,由于某种原因,该函数没有获取信息,因此值仍为零。这是时间问题吗?
I tried to put a loop after the function verifyUser() but it never gets
我试图在函数verifyUser()之后放置一个循环,但它永远不会得到
out:
while user.email == nil {
print("Waiting...")
}
So... thats the question
所以...这就是问题所在
Thanks!
谢谢!
edit for Anas Menhar This is my struct. Why would it be better to be a NSObject? I did a Struct because I could do two different inits (one empty) and the NsObject didn't let me for some reason
编辑Anas Menhar这是我的结构。为什么成为NSObject会更好?我做了一个Struct,因为我可以做两个不同的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
}
}
edit for Hitesh
为Hitesh编辑
if I print the dictionary it prints just at the same time that the user completed with the information. At the end of everything.
如果我打印字典,它就会在用户完成信息的同时打印。一切都结束了。
1 个解决方案
#1
1
The issue is that viewDidLoad()
calls verifyUser()
before printing "viewdidload user: \(user)"
. Everything in verifyUser()
will finish (with exception to your network call) before the print.
问题是viewDidLoad()在打印“viewdidload user:\(user)”之前调用verifyUser()。在打印之前,verifyUser()中的所有内容都将完成(网络调用除外)。
So here is the sequence of events happening for you:
所以这是发生在你身上的一系列事件:
super.viewDidLoad()
- super.viewDidLoad()
-
verifyUser()
is called - 调用verifyUser()
- print statement that is in
verifyUser()
- 在verifyUser()中的print语句
- guard statement that is in
verifyUser()
- 在verifyUser()中的guard语句
- print statement in
viewDidLoad()
- viewDidLoad()中的print语句
super.viewDidAppear()
- super.viewDidAppear()
- print in
super.viewDidAppear()
- 在super.viewDidAppear()中打印
Everything inside the closure for the .observeSingleEventOf will happen some point after 4 -- whenever that call finishes. If you want to do something when the call is finished, put it in the closure.
关闭.observeSingleEventOf的闭包内的所有内容都将在4之后的某个时刻发生 - 每当调用结束时。如果您想在呼叫结束时执行某些操作,请将其放入闭包中。
Like this:
喜欢这个:
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)
}
The places where I added comments are the places that would potentially be called when that request completes.
我添加注释的位置是该请求完成时可能会调用的位置。
Side note: If you are going to use a Struct for AppUser, just make sure you know the differences between structs and classes. You could have a class named AppUser and have two different inits like this:
附注:如果您打算使用Struct for AppUser,只需确保您知道结构和类之间的差异。你可以有一个名为AppUser的类,它有两个不同的命令,如下所示:
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@email.com",
"completedRegister": "true",
"FULLUser": "true"])
///user1 properties:
id: Optional("12342")
- some: "12342"
name: Optional("John Doe")
- some: "John Doe"
email: Optional("email@email.com")
- some: "email@email.com"
completedRegister: Optional(true)
- some: true
FULLUser: Optional(true)
- some: true
let user2 = AppUser()
///user2 properties: none
#1
1
The issue is that viewDidLoad()
calls verifyUser()
before printing "viewdidload user: \(user)"
. Everything in verifyUser()
will finish (with exception to your network call) before the print.
问题是viewDidLoad()在打印“viewdidload user:\(user)”之前调用verifyUser()。在打印之前,verifyUser()中的所有内容都将完成(网络调用除外)。
So here is the sequence of events happening for you:
所以这是发生在你身上的一系列事件:
super.viewDidLoad()
- super.viewDidLoad()
-
verifyUser()
is called - 调用verifyUser()
- print statement that is in
verifyUser()
- 在verifyUser()中的print语句
- guard statement that is in
verifyUser()
- 在verifyUser()中的guard语句
- print statement in
viewDidLoad()
- viewDidLoad()中的print语句
super.viewDidAppear()
- super.viewDidAppear()
- print in
super.viewDidAppear()
- 在super.viewDidAppear()中打印
Everything inside the closure for the .observeSingleEventOf will happen some point after 4 -- whenever that call finishes. If you want to do something when the call is finished, put it in the closure.
关闭.observeSingleEventOf的闭包内的所有内容都将在4之后的某个时刻发生 - 每当调用结束时。如果您想在呼叫结束时执行某些操作,请将其放入闭包中。
Like this:
喜欢这个:
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)
}
The places where I added comments are the places that would potentially be called when that request completes.
我添加注释的位置是该请求完成时可能会调用的位置。
Side note: If you are going to use a Struct for AppUser, just make sure you know the differences between structs and classes. You could have a class named AppUser and have two different inits like this:
附注:如果您打算使用Struct for AppUser,只需确保您知道结构和类之间的差异。你可以有一个名为AppUser的类,它有两个不同的命令,如下所示:
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@email.com",
"completedRegister": "true",
"FULLUser": "true"])
///user1 properties:
id: Optional("12342")
- some: "12342"
name: Optional("John Doe")
- some: "John Doe"
email: Optional("email@email.com")
- some: "email@email.com"
completedRegister: Optional(true)
- some: true
FULLUser: Optional(true)
- some: true
let user2 = AppUser()
///user2 properties: none