1

I am working with Parse and would like to download images for offline use. I understand that this is not possible with Local Datastore so I have decided to add them to Core Data.

I have successfully downloaded the PFFiles and put them in to an Array. I am then trying to create an Array for the NSData, but the Array count is always 0 when I use the code below

class DealsDownloadViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!

var trailID = [Int]()
var trailStep = [Int]()
var dealNumber = [Int]()
var imageFile = [PFFile]()
var imagesArray = [UIImage]()
var imageDataArray = [NSData]()
var number = 0

override func viewDidLoad() {
    super.viewDidLoad()


    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    let context: NSManagedObjectContext = appDel.managedObjectContext


    let dealsQuery = PFQuery(className: ("Deals"))
    dealsQuery.orderByAscending("TrailId")

    dealsQuery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
        if let objects = objects {

            for object in objects {


                self.trailID.append(object["TrailID"] as! Int)
                self.trailStep.append(object["TrailStep"] as! Int)
                self.dealNumber.append(object["dealNumber"] as! Int)
                self.imageFile.append(object["dealImage"] as! PFFile!)


            }

            for file in self.imageFile {

                let dealImage = file
                dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in

                    if error == nil {

                        let image = UIImage(data: imageData!)
                        self.imageDataArray.append(imageData!)
                        self.imagesArray.append(image!)

                    } else {print("error here")}

                })

                print(self.trailID.count)
                print(self.trailStep.count)
                print(self.dealNumber.count)
                print(self.imageDataArray.count)
                print(self.imagesArray.count)
            }





        } else {print("problem making arrays")}


        }

}

Log from the original code

If I move the Print statement up, I just get it printing every iteration of the loop.

for file in self.imageFile {

                let dealImage = file
                dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in

                    if error == nil {

                        let image = UIImage(data: imageData!)
                        self.imageDataArray.append(imageData!)
                        self.imagesArray.append(image!)

                    } else {print("error here")}

                    print(self.trailID.count)
                    print(self.trailStep.count)
                    print(self.dealNumber.count)
                    print(self.imageDataArray.count)
                    print(self.imagesArray.count)

                })


            }


        } else {print("problem making arrays")}


        }

}

Log from second code

In this case I can see that the data is added to both the imagesArray and imageDataArray.

This seems like such a simple issue but I am going crazy over it. What am I doing wrong, and is this the most efficient way of adding this data to Core Data? Am I overlooking something obvious?

I am new to programming so please do point out any mistakes I have made, and I am especially new as a questioner to stackoverflow (you have been indispensable while learning) so please let me know if you need any information that I have missed.

Thanks for your help.

Update 1

I have tried editing the code as explained in the comments and I am still getting the same result. I have moved the Print statement around on this code and it is still giving me the same results as above.

for file in self.imageFile {

                let dealImage = file

                dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in

                    if error == nil {

                        weak var aBlockSelf = self

                        let image = UIImage(data: imageData!)
                        aBlockSelf!.imageDataArray.append(imageData!)
                        self.imagesArray.append(image!)

                    }

                    print(self.trailID.count)
                    print(self.trailStep.count)
                    print(self.dealNumber.count)
                    print(self.imageDataArray.count)
                    print(self.imagesArray.count)

                })

            }

        } else {print("problem making arrays")}

    }

}

Am I missing something very simple? Thanks again for your help.

Update 2

This is the same code with (I think) the print statements moved outside of the For Loop. This is giving me counts of 9,9,9,0,0 from the print statements, whereas I think I should be expecting 9,9,9,9,9.

for file in self.imageFile {

                let dealImage = file

                dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in

                    if error == nil {

                        weak var aBlockSelf = self

                        let image = UIImage(data: imageData!)
                        aBlockSelf!.imageDataArray.append(imageData!)
                        self.imagesArray.append(image!)

                    }

                })

            }

            print(self.trailID.count)
            print(self.trailStep.count)
            print(self.dealNumber.count)
            print(self.imageDataArray.count)
            print(self.imagesArray.count)

        } else {print("problem making arrays")}

    }

}

1 Answer 1

0

There is no issue here!

You are being deceived by the way asynchronous block works. Asynchronous block gets queued up to get executed some point later in next run loop.

Your first print statement is just after you pass the code to block which is yet to be executed. Which is why you do see your image array empty.

Sign up to request clarification or add additional context in comments.

14 Comments

Thanks a lot for your reply. I have read up a bit to try to better understand Asynchronous Blocks, but I can't work out how I can alter my code. Where should I move the print statement to? I have tried moving it all around the code but it never seems to give the 9,9,9,9,9 result that it should. Thanks again. I really appreciate your help as a newbie.
First of all, inside block, you should pass a weak reference to self object - like weak var aBlockSelf = self. And then calling it like aBlockSelf.imageDataArray.append(imageData!). You should move your print statement just after imagesArray is set inside the block.
I still seem to be getting the same results from the print statement. I have updated my original question to add the change that you suggested, and I have moved both the print statements and the aBlockSelf variable around that part of the code, but it keeps giving me the same 9,9,9,0,0 or 9,9,9,0,0,9,9,9,1,1...etc result. Am I still missing something? Thanks
Results looks good to me as you are fetching images in for loop and passing block in for loop so your image count will get updated by 1.
I think you've cracked it! Thanks a lot for your patience. I knew there must have been an easy answer. I think I need a bit more practice. I really appreciate your help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.