Search code examples
arraysswiftloopsscopefor-in-loop

Can I update a global array using a for-in loop, and use the updated array outside of the loop ? (Swift)


I am currently fetching ImageUrls from Firestore, and accessing them using a for-in loop. Within the for-in loop, I append to a global array using .append(). However, when I call the array outside of the for-in loop, it is empty. I read the response to this post 'IOS Swift value of an Integer is not being saved' which was helpful in understanding that my global array is empty because the for-in loop is being executed after I call my array, and how to overcome this problem when using a closure - but how can I achieve the same result when using a for-in loop ? Any direct help or links to helpful articles/videos/posts will be much appreciated.

I know there are similar posts to this, but I went through them and there was only the one I referenced above referring to this problem in swift, so I read that but still struggling. Will attach code below:

// global array of strings which I want to append to:

var tuwoImageUrls = [String]()

internal var tuwos: [Tuwo]? {
    didSet {
        self.pickerView.pickerView.reloadData()
    }
}

// function fetching documents ('tuwos') from firestore:

func fetchTuwos(completion handler: @escaping ([Tuwo]?, Error?) -> ()) {
    guard let uid = Auth.auth().currentUser?.uid else {
        return handler(nil, nil)
    }

    Firestore.firestore()
        .collection("tuwos").document(uid).collection("tuwos")
        .getDocuments { (querySnapshot, error) in
            handler(querySnapshot?.documents.compactMap({
                Tuwo(dictionary: $0.data())
            }), error)
        }
}

// calling function, accessing documents to append ImageUrl to global array ('tuwoImageUrls') using for-in loop:

    fetchTuwos { [weak self] (tuwos, error) in
        self?.tuwos = tuwos

        DispatchQueue.main.async {
            for tuwo in self!.tuwos! {
                let tuwoImageUrl = "\(tuwo.profileImageUrl)"
                self!.tuwoImageUrls.append("\(tuwoImageUrl)")
                self!.pickerView.pickerView.reloadData()
            }
        }

    }

// calling a print statement of the array outside of the scope of fetchTuwos returns an empty array

    print("The Urls:" , tuwoImageUrls)

// my 'Tuwo' struct

struct Tuwo {
let name, profileImageUrl, uid: String

init(dictionary: [String: Any]) {
    self.name = dictionary["name"] as? String ?? ""
    self.profileImageUrl = dictionary["profileImageUrl"] as? String ?? ""
    self.uid = dictionary["uid"] as? String ?? ""
}}

Solution

  • I hope this solution helps

    fetchTuwos { [weak self] (tuwos, error) in
        self?.tuwos = tuwos
        self?.tuwoImageUrls = tuwos?.map { "\($0.profileImageUrl)" } ?? []
    
        DispatchQueue.main.async { [weak self] in
            self?.pickerView.pickerView.reloadData()
        }
        print("\(tuwoImageUrls)")
    
    }