-3

I'm a bit of a Swift newbie, and I've run into a problem that is really stumping me...

In the code below:

class TestViewController: UIViewController {

  var userNames : [String] = {return DatabaseMethods.getUsers()}()

  override func viewDidLoad() {
    super.viewDidLoad()
    print(userNames)
  }
}

The print statement will print an empty array every time. (I) I'm not sure why this is happening, and (II) I haven't figured out a way to get around this issue. Just for a bit more context, Here is what the DatabaseMethods class looks like:

class DatabaseMethods {

static func getUsers() -> [String] {
    var userNames = [String]()
    db.collection("users").getDocuments() { (querySnapshot, err) in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            for document in querySnapshot!.documents {
                let data = document.data()
                let first : String = data["First"] as! String
                let last : String = data["Last"] as! String
                userNames.append("\(first) \(last)")
            }
        }
    }
    return userNames
}

}
T. Fo
  • 199
  • 2
  • 6

2 Answers2

-1

Use the viewdidload method to make the petition, i hope your method is not executed because you are not intialize in viewdidload and you have an asynchronous problem. Try to make some like this:

class TestViewController: UIViewController {

  var userNames : [String] = []

  override func viewDidLoad() {
    super.viewDidLoad()
    userNames = DatabaseMethods.getUsers()
    print(userNames)
  }
}

in your code you are trying to make a lazy var, not just a var.

-3

db.collection(“users“).getDocuments() is asynchronous, that is why it takes a closure. With DispatchGroup you can make getUsers() synchronous so you get all users back at the end of the call.

static func getUsers() -> [String] {
    let group = DispatchGroup()
    group.join()
    var userNames = [String]()
    db.collection("users").getDocuments() { (querySnapshot, err) in
        defer { group.leave() }
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            for document in querySnapshot!.documents {
                let data = document.data()
                let first : String = data["First"] as! String
                let last : String = data["Last"] as! String
                userNames.append("\(first) \(last)")
            }
        }
    }
    group.wait()
    return userNames
}

Since arrays are value-types an empty copy would have been returned and so updates would not have reached it either with the old method, since value-types are getting copied as opposed to reference-types which are not.

Fabian
  • 5,040
  • 2
  • 23
  • 35