26

I am trying to use the UIActivityViewControllerCompletionHandler , but i dont quite get how..

I want to detect when the user finishes or dismisses this view controller (UIActivityViewController).

Anyone knows how?

Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
Emre Akman
  • 1,212
  • 3
  • 19
  • 25

6 Answers6

70

Here's how you show a sharing dialog and set its completion handler

NSArray *imageArray = [NSArray arrayWithObject:shareImage];

UIActivityViewController *sharing = [[UIActivityViewController alloc] initWithActivityItems:imageArray applicationActivities:nil];

[sharing setCompletionHandler:^(NSString *activityType, BOOL completed) {
    NSLog(@"completed dialog - activity: %@ - finished flag: %d", activityType, completed);
}];

[self presentViewController:sharing animated:YES completion:nil];
gchbib
  • 1,955
  • 1
  • 17
  • 23
25

With iOS 8 completionHandler is deprecated, so you will want to provide alternative completionWithItemsHandler. It also allows to handle if extension modified data you set (say Photo extension). See Documentation

    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[text, URL, image] applicationActivities:nil];
    activityViewController.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeAirDrop, UIActivityTypeAddToReadingList];

    // check if new API supported
    if ([activityViewController respondsToSelector:@selector(completionWithItemsHandler)]) {
        activityViewController.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
            // When completed flag is YES, user performed specific activity
        };
    } else {
        activityViewController.completionHandler = ^(NSString *activityType, BOOL completed) {
            // When completed flag is YES, user performed specific activity
        };
    }
Anton Gaenko
  • 8,929
  • 6
  • 44
  • 39
19
typedef void (^UIActivityViewControllerCompletionHandler)
    (NSString *activityType, BOOL completed);

The second parameter of the completion handler tells you whether the user dismissed the controller. If they dismissed the controller, completed will be set to NO.

There's more details in the completion handler's documentation.

sobri
  • 1,626
  • 15
  • 28
  • 1
    Hey dude, how can I know whether I have post successfully? Because even the post is failed indeed, the "completed" remains also Yes/1 – Paradise – Paradise Sep 11 '13 at 07:26
1

Swift 5:

func showShareOf(url: URL, title: String) {
    let shareItems: [Any] = ["\(title)\n", url]
    let activityVC = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
    activityVC.completionWithItemsHandler = doneSharingHandler
    self.present(activityVC, animated: true, completion: nil)
}

@objc func doneSharingHandler(activityType: UIActivity.ActivityType?, completed: Bool, _ returnedItems: [Any]?, error: Error?) {
    if (!completed) { return }
    // If here, log which activity occurred
    print("Shared activity: \(activityType)")
}
Bill Patterson
  • 2,495
  • 1
  • 19
  • 20
0

You can use completionWithItemsHandler

Here is the code in Objective-C. Please translate it into Swift accordingly.

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[text] applicationActivities:nil];

activityVC.completionWithItemsHandler  = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *error){
          
   if (completed) {
             
        NSLog(@"Shared by activity %@", activityType);

    } else {
        NSLog(@"ShareSheet was closed");
    }
   
    if (error) {
        NSLog(@"An Error Occured: %@, %@", error.localizedDescription, error.localizedFailureReason);
             
    }
};
Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
-1

For Swift, this one works for me...

    // Configure UIActivityViewController
    let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityViewController.excludedActivityTypes = [UIActivityTypeAirDrop,
        UIActivityTypeAddToReadingList,
        UIActivityTypeAssignToContact,
        UIActivityTypePrint,
        UIActivityTypeCopyToPasteboard]

    // Show UIActivityViewController
    presentViewController(activityViewController, animated: true, completion: nil)

    // Define completion handler
    activityViewController.completionWithItemsHandler = doneSharingHandler

...

func doneSharingHandler(activityType: String!, completed: Bool, returnedItems: [AnyObject]!, error: NSError!) {

    // Return if cancelled
    if (!completed) {
        return
    }
    // If here, log which activity occurred
    println("Shared video activity: \(activityType)")
}