UIActivityViewController completion handler still calls action if user presses cancel
-
24-12-2019 - |
Question
In my UIActivityViewController, I use completion handler to execute a "successfully shared" notification. It works but my only problem is, it still shows the notification if the user presses cancel.
Here is my completion handler code,
[controller setCompletionHandler:^(NSString *activityType, BOOL completed) {
CWStatusBarNotification *notification = [CWStatusBarNotification new];
[notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
forDuration:3.0f];
notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
notification.notificationLabelTextColor = [UIColor whiteColor];
}];
Thanks for the help!
Solution
That's what the completed
argument is for:
[controller setCompletionHandler:^(NSString *activityType, BOOL completed) {
if (!completed) return;
CWStatusBarNotification *notification = [CWStatusBarNotification new];
[notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
forDuration:3.0f];
notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
notification.notificationLabelTextColor = [UIColor whiteColor];
}];
OTHER TIPS
Note: the completionHandler property is deprecated in iOS8, so it's not possible anymore to know the result of a share action.
https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622010-completionhandler
Update: Like adruzh said, on iOS8 there's a new completionHandler that Apple forgot to mention in the documentation:
[activityController setCompletionWithItemsHandler:
^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
}];
For Swift, this is what worked for us:
...
// 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)")
}
For the Swifties out there, here's how you would code this in Swift along with some share service detection:
activityViewController.completionHandler = {(activityType, completed:Bool) in
if !completed {
//cancelled
return
}
//shared successfully
//below is how you would detect for different sharing services
var activity:String = "other"
if activityType == UIActivityTypePostToTwitter {
activity = "twitter"
}
if activityType == UIActivityTypeMail {
activity = "mail"
}
//more code here if you like
}
The completed
parameter will be NO
is the user cancels.
[controller setCompletionHandler:^(NSString *activityType, BOOL completed) {
if (completed) {
CWStatusBarNotification *notification = [CWStatusBarNotification new];
[notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
forDuration:3.0f];
notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
notification.notificationLabelTextColor = [UIColor whiteColor];
}
}];
SWIFT 2.0, iOS 8.0 >, you should use completion handler like this:
self.presentViewController(activityVC, animated: true, completion: nil)
activityVC.completionWithItemsHandler = {(activityType, completed:Bool, returnedItems:[AnyObject]?, error: NSError?) in
//do some action
}
see my answer here: https://stackoverflow.com/a/34581940/1109892
Swift 3
func completionHandler(activityType: UIActivityType?, shared: Bool, items: [Any]?, error: Error?) {
if (shared) {
print("Cool user shared some stuff")
}
else {
print("Bad user canceled sharing :(")
}
}
activityController.completionWithItemsHandler = completionHandler