user3746428
user3746428

Reputation: 11175

Image download slows UIActivityViewController appearance time

I have a share button in a UITableViewCell action which pulls up a UIActivityViewController. This works absolutely fine, apart from the fact that I'm loading an image from Parse, and as the image is fairly high resolution, can make the UIActivityViewController slow to appear. I have added a UIActivityIndicator to the navigation bar to notify the user that something in loading, but it still isn't the best user experience.

I was wondering if there is anyway that I can make the UIActivityViewController appear straight away while simultaneously loading the image in the background so that it is added to the share when it is loaded? Either that or is there a way to start loading the image as soon as the user swipes the UITableViewCell?

If anyone has any other suggestions, then they would be much appreciated!

Thanks!

EDIT:

Here is the code I have:

    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0)) {
            let imageURL = NSURL(string: DataManager.sharedInstance.getRideByName(cell.rideNameLabel.text!)!.rideImage!)
            let imageData = NSData(contentsOfURL: imageURL!)

            dispatch_async(dispatch_get_main_queue()) {
                let image = UIImage(data: imageData!)
                let text = "I've just been to '\(cell.rideNameLabel.text!)' at \(self.parkPassed.name!)!"
                let appURL = NSURL(string: "http://itunes.apple.com/app/1021402097")

                let objectsToShare = [text, image!, appURL!]
                let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
                activityVC.excludedActivityTypes = [UIActivityTypeAddToReadingList, UIActivityTypeAssignToContact, UIActivityTypeCopyToPasteboard, UIActivityTypePostToFlickr, UIActivityTypePostToTencentWeibo, UIActivityTypePostToVimeo, UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeSaveToCameraRoll]

                self.presentViewController(activityVC, animated: true, completion: nil)

                self.navigationItem.titleView = nil
            }
        }

Upvotes: 1

Views: 553

Answers (1)

Dave S
Dave S

Reputation: 3468

You can use Parse's PFImageView which uses a placeholder image that is stored locally. So the view will load immediately and once your controller has finished initializing you can tell Parse to load the image in the background and it should do the rest for you.

PFImageView *creature = [[PFImageView alloc] init];
creature.image = [UIImage imageNamed:@”1.jpg”]; // placeholder image
creature.file = (PFFile *)file;
[creature loadInBackground];

See this link for more details.

EDIT

Additionally just about every Parse action has a download in background with completion block version. You can download the image in the background and set the image in the completion block.

I'm not seeing any Parse references in your code, but it looks like it might be inside your DataManager. What it looks like you are doing is downloading the data first in the background, then upon completion you are presenting the UIActivityViewController.

Instead what I would do is create a custom UIActivityViewController, you would use it the same way except you would set image to be a placeholder image and create a custom property to hold the Image URL you wish to load. Then in onViewDidAppear of your custom UIActivityViewController you can start a PFQuery or some other Async task to download the image data in the background and upon completion you can load the real image and dismiss any UIActivityIndictators you may be showing.

PFQuery *query = [PFQuery queryWithClassName:@"myImages"];
[query whereKey:@"imageName" equalTo:@"your_image.jpg"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
  if (!error) {
    // The find succeeded.
    NSLog(@"Successfully retrieved %d images.", objects.count);
    // Do something with the found objects
    for (PFObject *object in objects) {
        NSLog(@"%@", object.objectId);
    }
  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];

See this question for more details on downloading a Image using a PFQuery.

Upvotes: 2

Related Questions