From 13ad5af7c378f6b47c0ec4ad34b55bce38883526 Mon Sep 17 00:00:00 2001 From: yasirkula Date: Sat, 10 Dec 2022 18:41:11 +0300 Subject: [PATCH] Fixed share dialog not disappearing automatically when canceling a share operation on iPhones (which could lead to share callback being called multiple times) --- Plugins/NativeShare/README.txt | 2 +- Plugins/NativeShare/iOS/NativeShare.mm | 49 ++++++++++++++++---------- package.json | 2 +- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Plugins/NativeShare/README.txt b/Plugins/NativeShare/README.txt index b3c76ef..d4b3533 100644 --- a/Plugins/NativeShare/README.txt +++ b/Plugins/NativeShare/README.txt @@ -1,4 +1,4 @@ -= Native Share for Android & iOS (v1.4.8) = += Native Share for Android & iOS (v1.4.9) = Online documentation & example code available at: https://github.com/yasirkula/UnityNativeShare E-mail: yasirkula@gmail.com diff --git a/Plugins/NativeShare/iOS/NativeShare.mm b/Plugins/NativeShare/iOS/NativeShare.mm index 5825480..18ab996 100644 --- a/Plugins/NativeShare/iOS/NativeShare.mm +++ b/Plugins/NativeShare/iOS/NativeShare.mm @@ -85,10 +85,7 @@ - (NSString *)activityViewController:(UIActivityViewController *)activityViewCon [items addObject:[NSURL fileURLWithPath:filePath]]; } - UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil]; - if( strlen( subject ) > 0 ) - [activity setValue:[NSString stringWithUTF8String:subject] forKey:@"subject"]; - else if( [items count] == 0 ) + if( strlen( subject ) == 0 && [items count] == 0 ) { NSLog( @"Share canceled because there is nothing to share..." ); UnitySendMessage( "NSShareResultCallbackiOS", "OnShareCompleted", "2" ); @@ -96,35 +93,51 @@ - (NSString *)activityViewController:(UIActivityViewController *)activityViewCon return; } - if( CHECK_IOS_VERSION( @"8.0" ) ) + UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil]; + if( strlen( subject ) > 0 ) + [activity setValue:[NSString stringWithUTF8String:subject] forKey:@"subject"]; + + void (^shareResultCallback)(UIActivityType activityType, BOOL completed, UIActivityViewController *activityReference) = ^void( UIActivityType activityType, BOOL completed, UIActivityViewController *activityReference ) { - activity.completionWithItemsHandler = ^( UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError ) + NSLog( @"Shared to %@ with result: %d", activityType, completed ); + + if( activityReference ) { - NSLog( @"Shared to %@ with result: %d", activityType, completed ); - - if( activityError != nil ) - NSLog( @"Share error: %@", activityError ); - const char *resultMessage = [[NSString stringWithFormat:@"%d%@", completed ? 1 : 2, activityType] UTF8String]; char *result = (char*) malloc( strlen( resultMessage ) + 1 ); strcpy( result, resultMessage ); UnitySendMessage( "NSShareResultCallbackiOS", "OnShareCompleted", result ); + + // On iPhones, the share sheet isn't dismissed automatically when share operation is canceled, do that manually here + if( !completed && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ) + [activityReference dismissViewControllerAnimated:NO completion:nil]; + } + else + NSLog( @"Share result callback is invoked multiple times!" ); + }; + + if( CHECK_IOS_VERSION( @"8.0" ) ) + { + __block UIActivityViewController *activityReference = activity; // About __block usage: https://gist.github.com/HawkingOuYang/b2c9783c75f929b5580c + activity.completionWithItemsHandler = ^( UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError ) + { + if( activityError != nil ) + NSLog( @"Share error: %@", activityError ); + + shareResultCallback( activityType, completed, activityReference ); + activityReference = nil; }; } else if( CHECK_IOS_VERSION( @"6.0" ) ) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" + __block UIActivityViewController *activityReference = activity; activity.completionHandler = ^( UIActivityType activityType, BOOL completed ) { - NSLog( @"Shared to %@ with result: %d", activityType, completed ); - - const char *resultMessage = [[NSString stringWithFormat:@"%d%@", completed ? 1 : 2, activityType] UTF8String]; - char *result = (char*) malloc( strlen( resultMessage ) + 1 ); - strcpy( result, resultMessage ); - - UnitySendMessage( "NSShareResultCallbackiOS", "OnShareCompleted", result ); + shareResultCallback( activityType, completed, activityReference ); + activityReference = nil; }; #pragma clang diagnostic pop } diff --git a/package.json b/package.json index 6b9eddf..bad2f0a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.yasirkula.nativeshare", "displayName": "Native Share", - "version": "1.4.8", + "version": "1.4.9", "documentationUrl": "https://github.com/yasirkula/UnityNativeShare", "changelogUrl": "https://github.com/yasirkula/UnityNativeShare/releases", "licensesUrl": "https://github.com/yasirkula/UnityNativeShare/blob/master/LICENSE.txt",