I am trying to load photos in Core Data but this requires some background threads, so it happens that my Object gets saved in Core Data without its photo, I get that photo is nil. And the same is happening with the photos of my groups.
In short, at each iteration I save an object in Core Data and the saving happens faster than the loading of my Photo data.
I tried Semaphors, barriers, groups,... but none worked. I am certainly doing something wrong but I don't know what. If someone could help me I would really appreciate, it has been 2 weeks I am struggling with this same problem. This is my code in a simplified version, the full version is accessible below:
// MARK - ViewDidLoad
override func viewDidLoad() {
// This method is only called once, so you want to create any controls or arrays here
super.viewDidLoad()
// Verifying connectivity to internet
if Reachability.isConnectedToNetwork() == true {
// Getting data from Parse + getDataInBackgroundWithBlock
}else{
}
}
// MARK - Action of the login button
@IBAction func loginBtn_click(sender: AnyObject) {
if usernameTxt.text == "" || passwordTxt.text == "" {
self.displayAlert("Error", message: "Please enter a username and password")
}else{
// MARK - Login the user
PFUser.logInWithUsernameInBackground(usernameTxt.text!, password: passwordTxt.text!) { (user, error) -> Void in
if error == nil {
let queue = dispatch_queue_create("com.karagan.app.queue", DISPATCH_QUEUE_CONCURRENT)
dispatch_async(queue, { () -> Void in
self.getObjectsFromQueryWithAscendingOrder("Add", key: "user", value: userName, ascendingOrder: "added", completionHandler: { (objects1) -> Void in
// Update of an array in background
})
})
dispatch_async(queue, { () -> Void in
// Update of an array in background
})
dispatch_async(queue, { () -> Void in
self.getObjectsFromQueryWithAscendingOrder("Group", key: "membersUsername", value: userName, ascendingOrder: "membersUsername", completionHandler: { (objects3) -> Void in
// Update of an array in background
// MARK - Adding all the users in Core data
for var i = 0; i < usersFromParseDataBase.count; i++ {
let entity = NSEntityDescription.entityForName("Users", inManagedObjectContext: self.managedObjectContext)
let newUser = Users(entity: entity!, insertIntoManagedObjectContext: self.managedObjectContext)
if self.arrayAddedUsers.contains(usersFromParseDataBase[i].username){
// Saving new records in Core Data
}
}
})
})
dispatch_async(queue, { () -> Void in
self.getObjectsFromQueryWithDescendingOrder("Group", key: "membersUsername", value: userName, descendingOrder: "conversationUpdate", completionHandler: { (objects4) -> Void in
if array.count == 2 {
// Getting data in background - photo.getDataInbackgroundWithBlock
}
}else{
// Getting data in background - photo.getDataInbackgroundWithBlock
}
}
})
})
dispatch_barrier_async(queue, { () -> Void in
// Doing some stuff in background which needs the data from threads above
})
}else{
// Print error from loginWithUsernaemInBackground
}
}
}
}
This is what gets displayed to the log, so you can clearly see that the barrier gets executed before the loading of pictures is done executing.
TEST 3 - interacting user has been saved to core data
Loading profile image
Loading profile image
Loading group image
Loading profile image
Loading profile image
9
5
Loading group image
Loading group image
Loading group image
Loading group image
The thing is that I need this data for other operations later. My code is not consistent.