How to resolve Escaping closure captures 'inout' parameter 'data'

Viewed 293

I have the following function in a separate swift file which I use to make Firebase calls for data:

func fetchPosts(data: inout [Post]) {
    
    postRef.observe(DataEventType.value) { (snapshot) in
        
        data.removeAll()     // ***Error thrown here***
        
        if snapshot.value is NSNull {
            
            
        } else {
            
            var counter: UInt = 0
            
            for item in snapshot.children {
                
                let userID = (item as! DataSnapshot).key
                
                self.postRef.child(userID).observe(DataEventType.value) { (snap) in
                    
                    counter = counter + 1
                    
                    for child in snap.children {
                        
                        if let snapshot = child as? DataSnapshot,
                            
                            let post = Post(snapshot: snapshot) {

                                data.append(post)   // ***Error thrown here***
                                
                            }

                        if (counter == snapshot.childrenCount) {
                            
                            data = data.sorted(by: { $0.id > $1.id })   // ***Error thrown here***
                            
                        }
                        
                    }
                    
                }
                
            }
            
        }
        
    }
    
}

In my view I have the following:

@State var posts: [Post] = [] // which is the place holder for the posts data

and then i have the following call

func fetchPosts() {
    
    postStore.fetchPosts(data: &posts)
    
}

Which calls the function above and passes the [Post] array by reference

My issue is that I get the following error Escaping closure captures 'inout' parameter 'data' in the above function and I can not figure out what I need to do to resolve it!?

Has anyone ever encountered this error and what do you do to resolve it!?

1 Answers

That won't work with @State, instead you have to use completion callback pattern, like

func fetchPosts() {
    self.posts = [] // reset
    postStore.fetchPosts() { newPosts in
       DispatchQueue.main.async {
         self.posts = newPosts
       }
    }
}

and fetching function

func fetchPosts(completion: @escaping ([Post]) -> () ) {

//  ...
        var data: [Post] = []   // data is a local variable
        
        // ... 

        if (counter == snapshot.childrenCount) {
            
            completion(data.sorted(by: { $0.id > $1.id }))
            
        }

//  ...
}
Related