I have a class in which I am trying to use some generic code to build arrays for multiple collection views and pass an array of data to the viewcontroller where the collection view is.
The problem I have just now is that the result is being passed to the completion handler before the query is complete.
What am I doing wrong here? Theoretically it should work I think.
import UIKit
import Parse
class BuildArray: UICollectionViewController {
class func buildArrayFromQuery(queryForCollection: String, sender: UIViewController, completeBlock: (_ result: Any) -> Void) {
struct collectionStruct {
var name : String
var description : String
var title : String
var image : PFFile
var id: String
}
var collectionArray = [collectionStruct]()
//var queryFromSource =
var fromClass = ""
var fromName = ""
var fromDescription = ""
var fromTitle = ""
var fromImage = ""
//------------------------------------------------------------- set the class to query based off the collection
if queryForCollection == "Pack" {
fromClass = "Pack"
fromName = "packName"
fromDescription = "packDescription"
fromTitle = "packTitle"
fromImage = "packImage"
} else if queryForCollection == "Part" {
fromClass = "Part"
fromName = "partName"
fromDescription = "partDescription"
fromTitle = "partTitle"
fromImage = "partImage"
}
//------------------------------------------------------------- check reachability and set LDS if required
var query = PFQuery(className: fromClass)
query.order(byAscending: fromName)
CheckReachability.setupReachability(hostName: nil) { (block) in
if (block) {
//var connected = true
} else {
//var connected = false
query.fromLocalDatastore()
}
}
//------------------------------------------------------------- find the objects
query.findObjectsInBackground(block: { (objects, error) in
if error != nil {
print(error!)
} else if let packs = objects {
//------------------------------------------------------------- if we have objects and were reachable unpin everthing so it can be updated
CheckReachability.setupReachability(hostName: nil) { (block) in
if (block) {
PFObject.unpinAllObjectsInBackground(withName: "packDataLDS")
}
}
//------------------------------------------------------------- if there are objects loop through
for object in packs {
print(fromName)
print(object)
let arrayName = object.object(forKey: fromName) as! String
let arrayDescription = object.object(forKey: fromDescription) as! String
let arrayTitle = object.object(forKey: fromTitle) as! String
let arrayImage = object.object(forKey: fromImage) as! PFFile
let arrayID = object.objectId as String!
collectionArray.append(collectionStruct(name: arrayName, description: arrayDescription, title: arrayTitle, image: arrayImage, id: arrayID!))
}
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// sender.collectionView?.reloadData()
// sender.collectionView?.layoutIfNeeded()
// sender.collectionView?.setScaledDesginParam(scaledPattern: .verticalCenter, maxScale: 1.0, minScale: 0.8, maxAlpha: 1.0, minAlpha: 0.5)
// sender.collectionView?.scaledVisibleCells()
//
//// if sender.collectionView?.dataSource?.collectionView(sender.collectionView!, cellForItemAt: IndexPath(item: 0, section: 0)) != nil {
//// //self.collectionView?.scrollToItem(at: IndexPath(item: self.packIndexLDS, section: 0), at: .centeredVertically, animated: true)
//// let rect = sender.collectionView.layoutAttributesForItem(at: IndexPath(item: sender.packIndexLDS, section: 0))?.frame
//// self.collectionView.scrollRectToVisible(rect!, animated: false)
//// }
// }
}
//------------------------------------------------------------- if we are reachable pin everthing
CheckReachability.setupReachability(hostName: nil) { (block) in
if (block) {
PFObject.pinAll(inBackground: objects, withName: "packDataLDS")
}
}
})
completeBlock(result: collectionArray)
}
}
You are calling
completeBlock(result: collectionArray)
outside the completion block for the query. Move it inside the query's completion block instead of after.You have:
but it needs to be: