From 9086c4612beb6e8bda4deff10779f051b59836a1 Mon Sep 17 00:00:00 2001 From: hudson Date: Wed, 23 Sep 2020 14:15:31 -0300 Subject: [PATCH 1/2] Creation of class ShareContent to store file url and type Creation of CustomSLComposeViewController to allow share video in Twitter and Facebook using SLCompositeViewController Use of CustomSLComposeViewController in method shareViaInternal to allow video share Updated shareViaWhatsapp and ShareViaInstagram to allow share of videos --- plugin.xml | 4 + src/ios/CustomSLComposeViewController.h | 10 + src/ios/CustomSLComposeViewController.m | 22 + src/ios/ShareContent.h | 16 + src/ios/ShareContent.m | 33 + src/ios/SocialSharing.m | 1371 ++++++++++++----------- 6 files changed, 780 insertions(+), 676 deletions(-) create mode 100644 src/ios/CustomSLComposeViewController.h create mode 100644 src/ios/CustomSLComposeViewController.m create mode 100644 src/ios/ShareContent.h create mode 100644 src/ios/ShareContent.m diff --git a/plugin.xml b/plugin.xml index 71db3c91..3d8d8ff0 100755 --- a/plugin.xml +++ b/plugin.xml @@ -55,6 +55,10 @@ + + + + diff --git a/src/ios/CustomSLComposeViewController.h b/src/ios/CustomSLComposeViewController.h new file mode 100644 index 00000000..eb09541d --- /dev/null +++ b/src/ios/CustomSLComposeViewController.h @@ -0,0 +1,10 @@ +#import +#import +#import + +@interface CustomSLComposeViewController:SLComposeViewController + +- (BOOL)addVideoURL:(NSURL *)url; + +@end + diff --git a/src/ios/CustomSLComposeViewController.m b/src/ios/CustomSLComposeViewController.m new file mode 100644 index 00000000..69564f46 --- /dev/null +++ b/src/ios/CustomSLComposeViewController.m @@ -0,0 +1,22 @@ +#import "CustomSLComposeViewController.h" +#import +#import +#import +#import + +// This class extends SLComposeViewController and adds ability of share videos +@implementation CustomSLComposeViewController + +- (BOOL)addVideoURL:(NSURL *)url { + NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithItem:url typeIdentifier:(NSString *)kUTTypeMPEG4]; + + NSExtensionItem *extensionItem = [NSExtensionItem new]; + extensionItem.attachments = [NSArray arrayWithObject:itemProvider]; + + return [self performSelector:@selector(addExtensionItem:) withObject:extensionItem]; +} + ++ (CustomSLComposeViewController *)composeViewControllerForServiceType:(NSString *)serviceType{ + return (CustomSLComposeViewController *)[super composeViewControllerForServiceType:serviceType]; +} +@end diff --git a/src/ios/ShareContent.h b/src/ios/ShareContent.h new file mode 100644 index 00000000..c9f57d48 --- /dev/null +++ b/src/ios/ShareContent.h @@ -0,0 +1,16 @@ +#import +#import + +typedef NS_ENUM(NSUInteger, ContentType) { + IMAGE, + VIDEO, + AUDIO, + OTHER +}; + +@interface ShareContent : NSObject +- (ContentType)getType; +- (void)setUrl:(NSURL *)url; +- (NSURL*)getUrl; +@end + diff --git a/src/ios/ShareContent.m b/src/ios/ShareContent.m new file mode 100644 index 00000000..9d72e35f --- /dev/null +++ b/src/ios/ShareContent.m @@ -0,0 +1,33 @@ +@implementation ShareContent { + NSURL * _url; + ContentType _type; +} + +- (ContentType)getType { + return _type; +}; + +- (void)setUrl:(NSURL *)url { + _url = url; + if (_url == nil) + return; + CFStringRef fileExtension = (__bridge CFStringRef) [url pathExtension]; + CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL); + CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType); + CFRelease(UTI); + NSString *type = (__bridge_transfer NSString *) MIMEType; + if ([type hasPrefix:@"image"]) + _type = IMAGE; + else if ([type hasPrefix:@"video"]) + _type = VIDEO; + else if ([type hasPrefix:@"audio"]) + _type = AUDIO; + else + _type = OTHER; +} + +- (NSURL *)getUrl { + return _url; +}; + +@end diff --git a/src/ios/SocialSharing.m b/src/ios/SocialSharing.m index ecb71b50..3748ff3a 100644 --- a/src/ios/SocialSharing.m +++ b/src/ios/SocialSharing.m @@ -1,5 +1,6 @@ #import "SocialSharing.h" #import "NSString+SSURLEncoding.h" +#import "ShareContent.h" #import #import #import @@ -14,848 +15,866 @@ static NSString *const kShareOptionIPadCoordinates = @"iPadCoordinates"; @implementation SocialSharing { - UIPopoverController *_popover; - NSString *_popupCoordinates; + UIPopoverController *_popover; + NSString *_popupCoordinates; } - (void)pluginInitialize { } -- (void)available:(CDVInvokedUrlCommand*)command { - BOOL avail = NO; - if (NSClassFromString(@"UIActivityViewController")) { - avail = YES; - } - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:avail]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +- (void)available:(CDVInvokedUrlCommand *)command { + BOOL avail = NO; + if (NSClassFromString(@"UIActivityViewController")) { + avail = YES; + } + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:avail]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (NSString*)getIPadPopupCoordinates { - // see https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin/issues/1052 - return nil; +- (NSString *)getIPadPopupCoordinates { + // see https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin/issues/1052 + return nil; } -- (void)setIPadPopupCoordinates:(CDVInvokedUrlCommand*)command { - _popupCoordinates = [command.arguments objectAtIndex:0]; +- (void)setIPadPopupCoordinates:(CDVInvokedUrlCommand *)command { + _popupCoordinates = [command.arguments objectAtIndex:0]; } -- (CGRect)getPopupRectFromIPadPopupCoordinates:(NSArray*)comps { - CGRect rect = CGRectZero; - if ([comps count] == 4) { - rect = CGRectMake([[comps objectAtIndex:0] integerValue], [[comps objectAtIndex:1] integerValue], [[comps objectAtIndex:2] integerValue], [[comps objectAtIndex:3] integerValue]); - } - return rect; +- (CGRect)getPopupRectFromIPadPopupCoordinates:(NSArray *)comps { + CGRect rect = CGRectZero; + if ([comps count] == 4) { + rect = CGRectMake([[comps objectAtIndex:0] integerValue], [[comps objectAtIndex:1] integerValue], [[comps objectAtIndex:2] integerValue], [[comps objectAtIndex:3] integerValue]); + } + return rect; } -- (void)share:(CDVInvokedUrlCommand*)command { - [self shareInternal:command - withOptions:@{ - kShareOptionMessage: [command.arguments objectAtIndex:0], - kShareOptionSubject: [command.arguments objectAtIndex:1], - kShareOptionFiles: [command.arguments objectAtIndex:2], - kShareOptionUrl: [command.arguments objectAtIndex:3], - kShareOptionIPadCoordinates: [command.arguments objectAtIndex:4] - } - isBooleanResponse:YES -]; +- (void)share:(CDVInvokedUrlCommand *)command { + [self shareInternal:command + withOptions:@{ + kShareOptionMessage: [command.arguments objectAtIndex:0], + kShareOptionSubject: [command.arguments objectAtIndex:1], + kShareOptionFiles: [command.arguments objectAtIndex:2], + kShareOptionUrl: [command.arguments objectAtIndex:3], + kShareOptionIPadCoordinates: [command.arguments objectAtIndex:4] + } + isBooleanResponse:YES + ]; } -- (void)shareWithOptions:(CDVInvokedUrlCommand*)command { - NSDictionary* options = [command.arguments objectAtIndex:0]; - [self shareInternal:command - withOptions:options - isBooleanResponse:NO - ]; +- (void)shareWithOptions:(CDVInvokedUrlCommand *)command { + NSDictionary *options = [command.arguments objectAtIndex:0]; + [self shareInternal:command + withOptions:options + isBooleanResponse:NO + ]; } -- (void)shareInternal:(CDVInvokedUrlCommand*)command withOptions:(NSDictionary*)options isBooleanResponse:(BOOL)boolResponse { +- (void)shareInternal:(CDVInvokedUrlCommand *)command withOptions:(NSDictionary *)options isBooleanResponse:(BOOL)boolResponse { if (!NSClassFromString(@"UIActivityViewController")) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; } - NSString *message = options[kShareOptionMessage]; - NSString *subject = options[kShareOptionSubject]; - NSArray *filenames = options[kShareOptionFiles]; + NSString *message = options[kShareOptionMessage]; + NSString *subject = options[kShareOptionSubject]; + NSArray *filenames = options[kShareOptionFiles]; NSString *urlString = options[kShareOptionUrl]; NSString *iPadCoordString = options[kShareOptionIPadCoordinates]; NSArray *iPadCoordinates; if (iPadCoordString != nil && iPadCoordString != [NSNull null]) { - iPadCoordinates = [iPadCoordString componentsSeparatedByString:@","]; + iPadCoordinates = [iPadCoordString componentsSeparatedByString:@","]; } else { - iPadCoordinates = @[]; + iPadCoordinates = @[]; } NSMutableArray *activityItems = [[NSMutableArray alloc] init]; - if (message != (id)[NSNull null] && message != nil) { - [activityItems addObject:message]; + if (message != (id) [NSNull null] && message != nil) { + [activityItems addObject:message]; } - if (filenames != (id)[NSNull null] && filenames != nil && filenames.count > 0) { - NSMutableArray *files = [[NSMutableArray alloc] init]; - for (NSString* filename in filenames) { - NSObject *file = [self getImage:filename]; - if (file == nil) { - file = [self getFile:filename]; + if (filenames != (id) [NSNull null] && filenames != nil && filenames.count > 0) { + NSMutableArray *files = [[NSMutableArray alloc] init]; + for (NSString *filename in filenames) { + NSObject *file = [self getImage:filename]; + if (file == nil) { + file = [self getFile:filename]; + } + if (file != nil) { + [files addObject:file]; + } } - if (file != nil) { - [files addObject:file]; - } - } - [activityItems addObjectsFromArray:files]; + [activityItems addObjectsFromArray:files]; } - if (urlString != (id)[NSNull null] && urlString != nil) { + if (urlString != (id) [NSNull null] && urlString != nil) { [activityItems addObject:[NSURL URLWithString:[urlString SSURLEncodedString]]]; } UIActivity *activity = [[UIActivity alloc] init]; NSArray *applicationActivities = [[NSArray alloc] initWithObjects:activity, nil]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities]; - if (subject != (id)[NSNull null] && subject != nil) { - [activityVC setValue:subject forKey:@"subject"]; + if (subject != (id) [NSNull null] && subject != nil) { + [activityVC setValue:subject forKey:@"subject"]; } if ([activityVC respondsToSelector:(@selector(setCompletionWithItemsHandler:))]) { - [activityVC setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray * returnedItems, NSError * activityError) { - if (completed == YES || activityType == nil) { - [self cleanupStoredFiles]; - } - if (boolResponse) { - [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:completed] - callbackId:command.callbackId]; - } else { - NSDictionary * result = @{@"completed":@(completed), @"app":activityType == nil ? @"" : activityType}; - [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result] - callbackId:command.callbackId]; - } - }]; + [activityVC setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { + if (completed == YES || activityType == nil) { + [self cleanupStoredFiles]; + } + if (boolResponse) { + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:completed] + callbackId:command.callbackId]; + } else { + NSDictionary *result = @{@"completed": @(completed), @"app": activityType == nil ? @"" : activityType}; + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result] + callbackId:command.callbackId]; + } + }]; } else { - // let's suppress this warning otherwise folks will start opening issues while it's not relevant + // let's suppress this warning otherwise folks will start opening issues while it's not relevant #pragma GCC diagnostic ignored "-Wdeprecated-declarations" [activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) { - if (completed == YES || activityType == nil) { - [self cleanupStoredFiles]; - } - NSDictionary * result = @{@"completed":@(completed), @"app":activityType == nil ? @"" : activityType}; - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + if (completed == YES || activityType == nil) { + [self cleanupStoredFiles]; + } + NSDictionary *result = @{@"completed": @(completed), @"app": activityType == nil ? @"" : activityType}; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:result]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }]; #pragma GCC diagnostic warning "-Wdeprecated-declarations" - } - - NSArray * socialSharingExcludeActivities = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"SocialSharingExcludeActivities"]; - if (socialSharingExcludeActivities!=nil && [socialSharingExcludeActivities count] > 0) { - activityVC.excludedActivityTypes = socialSharingExcludeActivities; - } - - dispatch_async(dispatch_get_main_queue(), ^(void){ - // iPad on iOS >= 8 needs a different approach - if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { - NSString* iPadCoords = [self getIPadPopupCoordinates]; - if (iPadCoords != nil && ![iPadCoords isEqual:@"-1,-1,-1,-1"]) { - CGRect rect; - if ([iPadCoordinates count] == 4) { - - rect = CGRectMake((int) [[iPadCoordinates objectAtIndex:0] integerValue], (int) [[iPadCoordinates objectAtIndex:1] integerValue], (int) [[iPadCoordinates objectAtIndex:2] integerValue], (int) [[iPadCoordinates objectAtIndex:3] integerValue]); - } else { - NSArray *comps = [iPadCoords componentsSeparatedByString:@","]; - rect = [self getPopupRectFromIPadPopupCoordinates:comps]; - } - if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) { + } + + NSArray *socialSharingExcludeActivities = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"SocialSharingExcludeActivities"]; + if (socialSharingExcludeActivities != nil && [socialSharingExcludeActivities count] > 0) { + activityVC.excludedActivityTypes = socialSharingExcludeActivities; + } + + dispatch_async(dispatch_get_main_queue(), ^(void) { + // iPad on iOS >= 8 needs a different approach + if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { + NSString *iPadCoords = [self getIPadPopupCoordinates]; + if (iPadCoords != nil && ![iPadCoords isEqual:@"-1,-1,-1,-1"]) { + CGRect rect; + if ([iPadCoordinates count] == 4) { + + rect = CGRectMake((int) [[iPadCoordinates objectAtIndex:0] integerValue], (int) [[iPadCoordinates objectAtIndex:1] integerValue], (int) [[iPadCoordinates objectAtIndex:2] integerValue], (int) [[iPadCoordinates objectAtIndex:3] integerValue]); + } else { + NSArray *comps = [iPadCoords componentsSeparatedByString:@","]; + rect = [self getPopupRectFromIPadPopupCoordinates:comps]; + } + if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // iOS 8.0 supported - activityVC.popoverPresentationController.sourceView = self.webView; - activityVC.popoverPresentationController.sourceRect = rect; + activityVC.popoverPresentationController.sourceView = self.webView; + activityVC.popoverPresentationController.sourceRect = rect; #endif - } else { - _popover = [[UIPopoverController alloc] initWithContentViewController:activityVC]; - _popover.delegate = self; - [_popover presentPopoverFromRect:rect inView:self.webView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; - } - } else if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) { + } else { + _popover = [[UIPopoverController alloc] initWithContentViewController:activityVC]; + _popover.delegate = self; + [_popover presentPopoverFromRect:rect inView:self.webView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; + } + } else if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // iOS 8.0 supported - activityVC.popoverPresentationController.sourceView = self.webView; - // position the popup at the bottom, just like iOS < 8 did (and iPhone still does on iOS 8) - CGRect rect; - if ([iPadCoordinates count] == 4) { - NSLog([[NSString alloc] initWithFormat:@"test %d", [[iPadCoordinates objectAtIndex:0] integerValue]]); - rect = CGRectMake((int) [[iPadCoordinates objectAtIndex:0] integerValue], (int) [[iPadCoordinates objectAtIndex:1] integerValue], (int) [[iPadCoordinates objectAtIndex:2] integerValue], (int) [[iPadCoordinates objectAtIndex:3] integerValue]); - } else { - NSArray *comps = [NSArray arrayWithObjects: - [NSNumber numberWithInt:(self.viewController.view.frame.size.width/2)-200], - [NSNumber numberWithInt:self.viewController.view.frame.size.height], - [NSNumber numberWithInt:400], - [NSNumber numberWithInt:400], - nil]; - rect = [self getPopupRectFromIPadPopupCoordinates:comps]; - } - activityVC.popoverPresentationController.sourceRect = rect; + activityVC.popoverPresentationController.sourceView = self.webView; + // position the popup at the bottom, just like iOS < 8 did (and iPhone still does on iOS 8) + CGRect rect; + if ([iPadCoordinates count] == 4) { + NSLog([[NSString alloc] initWithFormat:@"test %d", [[iPadCoordinates objectAtIndex:0] integerValue]]); + rect = CGRectMake((int) [[iPadCoordinates objectAtIndex:0] integerValue], (int) [[iPadCoordinates objectAtIndex:1] integerValue], (int) [[iPadCoordinates objectAtIndex:2] integerValue], (int) [[iPadCoordinates objectAtIndex:3] integerValue]); + } else { + NSArray *comps = [NSArray arrayWithObjects: + [NSNumber numberWithInt:(self.viewController.view.frame.size.width/2)-200], + [NSNumber numberWithInt:self.viewController.view.frame.size.height], + [NSNumber numberWithInt:400], + [NSNumber numberWithInt:400], + nil]; + rect = [self getPopupRectFromIPadPopupCoordinates:comps]; + } + activityVC.popoverPresentationController.sourceRect = rect; #endif + } } - } - [[self getTopMostViewController] presentViewController:activityVC animated:YES completion:nil]; + [[self getTopMostViewController] presentViewController:activityVC animated:YES completion:nil]; }); } -- (void)shareViaTwitter:(CDVInvokedUrlCommand*)command { - [self shareViaInternal:command type:SLServiceTypeTwitter]; +- (void)shareViaTwitter:(CDVInvokedUrlCommand *)command { + [self shareViaInternal:command type:SLServiceTypeTwitter]; } -- (void)shareViaFacebook:(CDVInvokedUrlCommand*)command { - [self shareViaInternal:command type:SLServiceTypeFacebook]; +- (void)shareViaFacebook:(CDVInvokedUrlCommand *)command { + [self shareViaInternal:command type:SLServiceTypeFacebook]; } -- (void)shareViaFacebookWithPasteMessageHint:(CDVInvokedUrlCommand*)command { - // If Fb app is installed a message is not prefilled. - // When shared through the default iOS widget (iOS Settings > Facebook) the message is prefilled already. - NSString *message = [command.arguments objectAtIndex:0]; - if (message != (id)[NSNull null]) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1000 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ - BOOL fbAppInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"fb://"]]; // requires whitelisting on iOS9 - if (fbAppInstalled) { - UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; - [pasteboard setValue:message forPasteboardType:@"public.utf8-plain-text"]; - NSString *hint = [command.arguments objectAtIndex:4]; - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:hint delegate:nil cancelButtonTitle:nil otherButtonTitles:nil]; - [alert show]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2800 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ - [alert dismissWithClickedButtonIndex:-1 animated:YES]; +- (void)shareViaFacebookWithPasteMessageHint:(CDVInvokedUrlCommand *)command { + // If Fb app is installed a message is not prefilled. + // When shared through the default iOS widget (iOS Settings > Facebook) the message is prefilled already. + NSString *message = [command.arguments objectAtIndex:0]; + if (message != (id) [NSNull null]) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1000 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ + BOOL fbAppInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"fb://"]]; // requires whitelisting on iOS9 + if (fbAppInstalled) { + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + [pasteboard setValue:message forPasteboardType:@"public.utf8-plain-text"]; + NSString *hint = [command.arguments objectAtIndex:4]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:hint delegate:nil cancelButtonTitle:nil otherButtonTitles:nil]; + [alert show]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2800 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ + [alert dismissWithClickedButtonIndex:-1 animated:YES]; + }); + } }); - } - }); - } - [self shareViaInternal:command type:SLServiceTypeFacebook]; -} - -- (void)shareVia:(CDVInvokedUrlCommand*)command { - [self shareViaInternal:command type:[command.arguments objectAtIndex:4]]; -} - -- (void)canShareVia:(CDVInvokedUrlCommand*)command { - NSString *via = [command.arguments objectAtIndex:4]; - CDVPluginResult * pluginResult; - if ([@"sms" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaSMS]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([@"email" caseInsensitiveCompare:via] == NSOrderedSame && [self isEmailAvailable]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([@"whatsapp" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaWhatsApp]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([@"instagram" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaInstagram]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([@"com.apple.social.facebook" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaFacebook]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([@"com.apple.social.twitter" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaTwitter]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else if ([self isAvailableForSharing:command type:via]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - } - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)canShareViaEmail:(CDVInvokedUrlCommand*)command { - if ([self isEmailAvailable]) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } else { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + } + [self shareViaInternal:command type:SLServiceTypeFacebook]; +} + +- (void)shareVia:(CDVInvokedUrlCommand *)command { + [self shareViaInternal:command type:[command.arguments objectAtIndex:4]]; +} + +- (void)canShareVia:(CDVInvokedUrlCommand *)command { + NSString *via = [command.arguments objectAtIndex:4]; + CDVPluginResult *pluginResult; + if ([@"sms" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaSMS]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([@"email" caseInsensitiveCompare:via] == NSOrderedSame && [self isEmailAvailable]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([@"whatsapp" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaWhatsApp]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([@"instagram" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaInstagram]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([@"com.apple.social.facebook" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaFacebook]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([@"com.apple.social.twitter" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaTwitter]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else if ([self isAvailableForSharing:command type:via]) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } } -- (bool)isEmailAvailable { - Class messageClass = (NSClassFromString(@"MFMailComposeViewController")); - return messageClass != nil && [messageClass canSendMail]; -} - -- (bool)isAvailableForSharing:(CDVInvokedUrlCommand*)command - type:(NSString *) type { - - // isAvailableForServiceType returns true if you pass it a type that is not - // in the defined constants, this is probably a bug on apples part - if(!([type isEqualToString:SLServiceTypeFacebook] - || [type isEqualToString:SLServiceTypeTwitter] - || [type isEqualToString:SLServiceTypeTencentWeibo] - || [type isEqualToString:SLServiceTypeSinaWeibo])) { - return false; - } - // wrapped in try-catch, because isAvailableForServiceType may crash if an invalid type is passed - @try { - return [SLComposeViewController isAvailableForServiceType:type]; - } - @catch (NSException* exception) { - return false; - } -} - -- (void)shareViaInternal:(CDVInvokedUrlCommand*)command - type:(NSString *) type { - - NSString *message = [command.arguments objectAtIndex:0]; - // subject is not supported by the SLComposeViewController - NSArray *filenames = [command.arguments objectAtIndex:2]; - NSString *urlString = [command.arguments objectAtIndex:3]; - - // boldly invoke the target app, because the phone will display a nice message asking to configure the app - SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:type]; - if (message != (id)[NSNull null]) { - [composeViewController setInitialText:message]; - } - - for (NSString* filename in filenames) { - UIImage* image = [self getImage:filename]; - if (image != nil) { - [composeViewController addImage:image]; - } - } - - if (urlString != (id)[NSNull null]) { - [composeViewController addURL:[NSURL URLWithString:[urlString SSURLEncodedString]]]; - } - - [composeViewController setCompletionHandler:^(SLComposeViewControllerResult result) { - if (SLComposeViewControllerResultCancelled == result) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"cancelled"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } else if (SLComposeViewControllerResultDone == result || [self isAvailableForSharing:command type:type]) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:true]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +- (void)canShareViaEmail:(CDVInvokedUrlCommand *)command { + if ([self isEmailAvailable]) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } else { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - // required for iOS6 (issues #162 and #167) - [self.viewController dismissViewControllerAnimated:YES completion:nil]; - }]; - [[self getTopMostViewController] presentViewController:composeViewController animated:YES completion:nil]; } -- (void)shareViaEmail:(CDVInvokedUrlCommand*)command { - if ([self isEmailAvailable]) { +- (bool)isEmailAvailable { + Class messageClass = (NSClassFromString(@"MFMailComposeViewController")); + return messageClass != nil && [messageClass canSendMail]; +} + +- (bool)isAvailableForSharing:(CDVInvokedUrlCommand *)command + type:(NSString *)type { - if (TARGET_IPHONE_SIMULATOR && IsAtLeastiOSVersion(@"8.0")) { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"SocialSharing plugin" - message:@"Sharing via email is not supported on the iOS 8 simulator." - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - return; + // isAvailableForServiceType returns true if you pass it a type that is not + // in the defined constants, this is probably a bug on apples part + if (!([type isEqualToString:SLServiceTypeFacebook] + || [type isEqualToString:SLServiceTypeTwitter] + || [type isEqualToString:SLServiceTypeTencentWeibo] + || [type isEqualToString:SLServiceTypeSinaWeibo])) { + return false; + } + // wrapped in try-catch, because isAvailableForServiceType may crash if an invalid type is passed + @try { + return [SLComposeViewController isAvailableForServiceType:type]; } + @catch (NSException *exception) { + return false; + } +} - [self cycleTheGlobalMailComposer]; +- (void)shareViaInternal:(CDVInvokedUrlCommand *)command + type:(NSString *)type { - self.globalMailComposer.mailComposeDelegate = self; + NSString *message = [command.arguments objectAtIndex:0]; + // subject is not supported by the SLComposeViewController + NSArray *filenames = [command.arguments objectAtIndex:2]; + NSString *urlString = [command.arguments objectAtIndex:3]; - if ([command.arguments objectAtIndex:0] != (id)[NSNull null]) { - NSString *message = [command.arguments objectAtIndex:0]; - BOOL isHTML = [message rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch].location != NSNotFound; - [self.globalMailComposer setMessageBody:message isHTML:isHTML]; + // boldly invoke the target app, because the phone will display a nice message asking to configure the app + SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:type]; + if (message != (id) [NSNull null]) { + [composeViewController setInitialText:message]; } - if ([command.arguments objectAtIndex:1] != (id)[NSNull null]) { - [self.globalMailComposer setSubject: [command.arguments objectAtIndex:1]]; + for (NSString *filename in filenames) { + ShareContent *content= [self getShareContent:filename]; + if(content!=nil){ + if([content getType]==IMAGE) + [composeViewController addImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[content getUrl]]]]; + else if([content getType]==VIDEO) + [composeViewController addVideoURL:[content getUrl]]; + } } - if ([command.arguments objectAtIndex:2] != (id)[NSNull null]) { - [self.globalMailComposer setToRecipients:[command.arguments objectAtIndex:2]]; + if (urlString != (id) [NSNull null]) { + [composeViewController addURL:[NSURL URLWithString:[urlString SSURLEncodedString]]]; } - if ([command.arguments objectAtIndex:3] != (id)[NSNull null]) { - [self.globalMailComposer setCcRecipients:[command.arguments objectAtIndex:3]]; - } + [composeViewController setCompletionHandler:^(SLComposeViewControllerResult result) { + if (SLComposeViewControllerResultCancelled == result) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"cancelled"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } else if (SLComposeViewControllerResultDone == result || [self isAvailableForSharing:command type:type]) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:true]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } else { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } + // required for iOS6 (issues #162 and #167) + [self.viewController dismissViewControllerAnimated:YES completion:nil]; + }]; + [[self getTopMostViewController] presentViewController:composeViewController animated:YES completion:nil]; +} + +- (void)shareViaEmail:(CDVInvokedUrlCommand *)command { + if ([self isEmailAvailable]) { + + if (TARGET_IPHONE_SIMULATOR && IsAtLeastiOSVersion(@"8.0")) { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"SocialSharing plugin" + message:@"Sharing via email is not supported on the iOS 8 simulator." + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alert show]; + return; + } - if ([command.arguments objectAtIndex:4] != (id)[NSNull null]) { - [self.globalMailComposer setBccRecipients:[command.arguments objectAtIndex:4]]; - } + [self cycleTheGlobalMailComposer]; - if ([command.arguments objectAtIndex:5] != (id)[NSNull null]) { - NSArray* attachments = [command.arguments objectAtIndex:5]; - NSFileManager* fileManager = [NSFileManager defaultManager]; - for (NSString* path in attachments) { - NSURL *file = [self getFile:path]; - NSData* data = [fileManager contentsAtPath:file.path]; + self.globalMailComposer.mailComposeDelegate = self; - if (!data) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid attachment"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; + if ([command.arguments objectAtIndex:0] != (id) [NSNull null]) { + NSString *message = [command.arguments objectAtIndex:0]; + BOOL isHTML = [message rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch].location != NSNotFound; + [self.globalMailComposer setMessageBody:message isHTML:isHTML]; } - NSString* fileName; - NSString* mimeType; - NSString* basename = [self getBasenameFromAttachmentPath:path]; - - //Find data anywhere in string - NSRange rangeData = [basename rangeOfString:@"data:"]; - if (rangeData.location == NSNotFound) - { - fileName = [basename pathComponents].lastObject; - mimeType = [self getMimeTypeFromFileExtension:[basename pathExtension]]; - } - else - { - mimeType = (NSString*)[[[basename substringFromIndex:rangeData.location+rangeData.length] componentsSeparatedByString: @";"] objectAtIndex:0]; - - //Find df anywhere in string - NSRange rangeDF = [basename rangeOfString:@"df:"]; - //If not found fallback to default name - if (rangeDF.location == NSNotFound) { - fileName = @"attachment."; - fileName = [fileName stringByAppendingString:(NSString*)[[mimeType componentsSeparatedByString: @"/"] lastObject]]; - } else { - //Found, apply name - fileName = (NSString*)[[[basename substringFromIndex:rangeDF.location+rangeDF.length] componentsSeparatedByString: @";"] objectAtIndex:0]; - } - - - NSString *base64content = (NSString*)[[basename componentsSeparatedByString: @","] lastObject]; - data = [SocialSharing dataFromBase64String:base64content]; - } - [self.globalMailComposer addAttachmentData:data mimeType:mimeType fileName:fileName]; - } - } - - // remember the command, because we need it in the didFinishWithResult method - _command = command; + if ([command.arguments objectAtIndex:1] != (id) [NSNull null]) { + [self.globalMailComposer setSubject:[command.arguments objectAtIndex:1]]; + } - dispatch_async(dispatch_get_main_queue(), ^{ - [[self getTopMostViewController] presentViewController:self.globalMailComposer animated:YES completion:nil]; - }); - } else { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } + if ([command.arguments objectAtIndex:2] != (id) [NSNull null]) { + [self.globalMailComposer setToRecipients:[command.arguments objectAtIndex:2]]; + } + + if ([command.arguments objectAtIndex:3] != (id) [NSNull null]) { + [self.globalMailComposer setCcRecipients:[command.arguments objectAtIndex:3]]; + } + + if ([command.arguments objectAtIndex:4] != (id) [NSNull null]) { + [self.globalMailComposer setBccRecipients:[command.arguments objectAtIndex:4]]; + } + + if ([command.arguments objectAtIndex:5] != (id) [NSNull null]) { + NSArray *attachments = [command.arguments objectAtIndex:5]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + for (NSString *path in attachments) { + NSURL *file = [self getFile:path]; + NSData *data = [fileManager contentsAtPath:file.path]; + + if (!data) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"invalid attachment"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + + NSString *fileName; + NSString *mimeType; + NSString *basename = [self getBasenameFromAttachmentPath:path]; + + //Find data anywhere in string + NSRange rangeData = [basename rangeOfString:@"data:"]; + if (rangeData.location == NSNotFound) { + fileName = [basename pathComponents].lastObject; + mimeType = [self getMimeTypeFromFileExtension:[basename pathExtension]]; + } else { + mimeType = (NSString *) [[[basename substringFromIndex:rangeData.location + rangeData.length] componentsSeparatedByString:@";"] objectAtIndex:0]; + + //Find df anywhere in string + NSRange rangeDF = [basename rangeOfString:@"df:"]; + //If not found fallback to default name + if (rangeDF.location == NSNotFound) { + fileName = @"attachment."; + fileName = [fileName stringByAppendingString:(NSString *) [[mimeType componentsSeparatedByString:@"/"] lastObject]]; + } else { + //Found, apply name + fileName = (NSString *) [[[basename substringFromIndex:rangeDF.location + rangeDF.length] componentsSeparatedByString:@";"] objectAtIndex:0]; + } + + + NSString *base64content = (NSString *) [[basename componentsSeparatedByString:@","] lastObject]; + data = [SocialSharing dataFromBase64String:base64content]; + } + [self.globalMailComposer addAttachmentData:data mimeType:mimeType fileName:fileName]; + } + } + + // remember the command, because we need it in the didFinishWithResult method + _command = command; + + dispatch_async(dispatch_get_main_queue(), ^{ + [[self getTopMostViewController] presentViewController:self.globalMailComposer animated:YES completion:nil]; + }); + } else { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } } -- (UIViewController*) getTopMostViewController { - UIViewController *presentingViewController = [[UIApplication sharedApplication] keyWindow].rootViewController; - while (presentingViewController.presentedViewController != nil) { - presentingViewController = presentingViewController.presentedViewController; - } - return presentingViewController; +- (UIViewController *)getTopMostViewController { + UIViewController *presentingViewController = [[UIApplication sharedApplication] keyWindow].rootViewController; + while (presentingViewController.presentedViewController != nil) { + presentingViewController = presentingViewController.presentedViewController; + } + return presentingViewController; } -- (NSString*) getBasenameFromAttachmentPath:(NSString*)path { - if ([path hasPrefix:@"base64:"]) { - NSString* pathWithoutPrefix = [path stringByReplacingOccurrencesOfString:@"base64:" withString:@""]; - return [pathWithoutPrefix substringToIndex:[pathWithoutPrefix rangeOfString:@"//"].location]; - } - return [path componentsSeparatedByString: @"?"][0]; +- (NSString *)getBasenameFromAttachmentPath:(NSString *)path { + if ([path hasPrefix:@"base64:"]) { + NSString *pathWithoutPrefix = [path stringByReplacingOccurrencesOfString:@"base64:" withString:@""]; + return [pathWithoutPrefix substringToIndex:[pathWithoutPrefix rangeOfString:@"//"].location]; + } + return [path componentsSeparatedByString:@"?"][0]; } -- (NSString*) getMimeTypeFromFileExtension:(NSString*)extension { - if (!extension) { - return nil; - } - // Get the UTI from the file's extension - CFStringRef ext = (CFStringRef)CFBridgingRetain(extension); - CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL); - // Converting UTI to a mime type - NSString *result = (NSString*)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType)); - CFRelease(ext); - CFRelease(type); - if (result == nil) { - result = @"application/octet-stream"; - } +- (NSString *)getMimeTypeFromFileExtension:(NSString *)extension { + if (!extension) { + return nil; + } + // Get the UTI from the file's extension + CFStringRef ext = (CFStringRef) CFBridgingRetain(extension); + CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL); + // Converting UTI to a mime type + NSString *result = (NSString *) CFBridgingRelease(UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType)); + CFRelease(ext); + CFRelease(type); + if (result == nil) { + result = @"application/octet-stream"; + } - return result; + return result; } /** * Delegate will be called after the mail composer did finish an action * to dismiss the view. */ -- (void) mailComposeController:(MFMailComposeViewController*)controller - didFinishWithResult:(MFMailComposeResult)result - error:(NSError*)error { - bool ok = result == MFMailComposeResultSent; - [self.globalMailComposer dismissViewControllerAnimated:YES completion:nil]; - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId]; +- (void)mailComposeController:(MFMailComposeViewController *)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error { + bool ok = result == MFMailComposeResultSent; + [self.globalMailComposer dismissViewControllerAnimated:YES completion:nil]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId]; } --(void)cycleTheGlobalMailComposer { - // we are cycling the damned GlobalMailComposer: http://stackoverflow.com/questions/25604552/i-have-real-misunderstanding-with-mfmailcomposeviewcontroller-in-swift-ios8-in/25604976#25604976 - self.globalMailComposer = nil; - self.globalMailComposer = [[MFMailComposeViewController alloc] init]; +- (void)cycleTheGlobalMailComposer { + // we are cycling the damned GlobalMailComposer: http://stackoverflow.com/questions/25604552/i-have-real-misunderstanding-with-mfmailcomposeviewcontroller-in-swift-ios8-in/25604976#25604976 + self.globalMailComposer = nil; + self.globalMailComposer = [[MFMailComposeViewController alloc] init]; } - (bool)canShareViaSMS { - Class messageClass = (NSClassFromString(@"MFMessageComposeViewController")); - return messageClass != nil && [messageClass canSendText]; -} - -- (void)shareViaSMS:(CDVInvokedUrlCommand*)command { - if ([self canShareViaSMS]) { - NSDictionary* options = [command.arguments objectAtIndex:0]; - NSString *phonenumbers = [command.arguments objectAtIndex:1]; - NSString *message = [options objectForKey:@"message"]; - NSString *subject = [options objectForKey:@"subject"]; - NSString *image = [options objectForKey:@"image"]; - - MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init]; - picker.messageComposeDelegate = (id) self; - if (message != (id)[NSNull null]) { - picker.body = message; - } - if (subject != (id)[NSNull null]) { - [picker setSubject:subject]; - } - if (image != nil && image != (id)[NSNull null]) { - BOOL canSendAttachments = [[MFMessageComposeViewController class] respondsToSelector:@selector(canSendAttachments)]; - if (canSendAttachments) { - NSURL *file = [self getFile:image]; - if (file != nil) { - [picker addAttachmentURL:file withAlternateFilename:nil]; + Class messageClass = (NSClassFromString(@"MFMessageComposeViewController")); + return messageClass != nil && [messageClass canSendText]; +} + +- (void)shareViaSMS:(CDVInvokedUrlCommand *)command { + if ([self canShareViaSMS]) { + NSDictionary *options = [command.arguments objectAtIndex:0]; + NSString *phonenumbers = [command.arguments objectAtIndex:1]; + NSString *message = [options objectForKey:@"message"]; + NSString *subject = [options objectForKey:@"subject"]; + NSString *image = [options objectForKey:@"image"]; + + MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init]; + picker.messageComposeDelegate = (id) self; + if (message != (id) [NSNull null]) { + picker.body = message; + } + if (subject != (id) [NSNull null]) { + [picker setSubject:subject]; + } + if (image != nil && image != (id) [NSNull null]) { + BOOL canSendAttachments = [[MFMessageComposeViewController class] respondsToSelector:@selector(canSendAttachments)]; + if (canSendAttachments) { + NSURL *file = [self getFile:image]; + if (file != nil) { + [picker addAttachmentURL:file withAlternateFilename:nil]; + } + } } - } - } - if (phonenumbers != (id)[NSNull null]) { - [picker setRecipients:[phonenumbers componentsSeparatedByString:@","]]; + if (phonenumbers != (id) [NSNull null]) { + [picker setRecipients:[phonenumbers componentsSeparatedByString:@","]]; + } + // remember the command, because we need it in the didFinishWithResult method + _command = command; + dispatch_async(dispatch_get_main_queue(), ^{ + picker.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + [[self getTopMostViewController] presentViewController:picker animated:NO completion:nil]; + }); + } else { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - // remember the command, because we need it in the didFinishWithResult method - _command = command; - dispatch_async(dispatch_get_main_queue(), ^{ - picker.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - [[self getTopMostViewController] presentViewController:picker animated:NO completion:nil]; - }); - } else { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } } // Dismisses the SMS composition interface when users taps Cancel or Send - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { - bool ok = result == MessageComposeResultSent; - [[self getTopMostViewController] dismissViewControllerAnimated:YES completion:nil]; - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId]; + bool ok = result == MessageComposeResultSent; + [[self getTopMostViewController] dismissViewControllerAnimated:YES completion:nil]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId]; } - (bool)canShareViaInstagram { - return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"instagram://app"]]; // requires whitelisting on iOS9 + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"instagram://app"]]; // requires whitelisting on iOS9 } - (bool)canShareViaWhatsApp { - return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"whatsapp://app"]]; // requires whitelisting on iOS9 + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"whatsapp://app"]]; // requires whitelisting on iOS9 } - (bool)canShareViaFacebook { - return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"fb://"]]; // requires whitelisting on iOS9 + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"fb://"]]; // requires whitelisting on iOS9 } - (bool)canShareViaTwitter { - return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"twitter://"]]; // requires whitelisting on iOS9 + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"twitter://"]]; // requires whitelisting on iOS9 } // this is only an internal test method for now, can be used to open a share sheet with 'Open in xx' links for tumblr, drive, dropbox, .. - (void)openImage:(NSString *)imageName { - UIImage* image =[self getImage:imageName]; - if (image != nil) { - NSString * savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/myTempImage.jpg"]; - [UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES]; - _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]]; - _documentInteractionController.UTI = @""; // TODO find the scheme for google drive and create a shareViaGoogleDrive function - [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated: YES]; - } -} - -- (void)shareViaInstagram:(CDVInvokedUrlCommand*)command { - - // on iOS9 canShareVia('instagram'..) will only work if instagram:// is whitelisted. - // If it's not, this method will ask permission to the user on iOS9 for opening the app, - // which is of course better than Instagram sharing not working at all because you forgot to whitelist it. - // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('instagram'..) - if (!IsAtLeastiOSVersion(@"9.0")) { - if (![self canShareViaInstagram]) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - } - - NSString *message = [command.arguments objectAtIndex:0]; - // subject is not supported by the SLComposeViewController - NSArray *filenames = [command.arguments objectAtIndex:2]; - - // only use the first image (for now.. maybe we can share in a loop?) - UIImage* image = nil; - for (NSString* filename in filenames) { - image = [self getImage:filename]; - break; - } + UIImage *image = [self getImage:imageName]; + if (image != nil) { + NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/myTempImage.jpg"]; + [UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES]; + _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]]; + _documentInteractionController.UTI = @""; // TODO find the scheme for google drive and create a shareViaGoogleDrive function + [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated:YES]; + } +} + +- (void)shareViaInstagram:(CDVInvokedUrlCommand *)command { + + // on iOS9 canShareVia('instagram'..) will only work if instagram:// is whitelisted. + // If it's not, this method will ask permission to the user on iOS9 for opening the app, + // which is of course better than Instagram sharing not working at all because you forgot to whitelist it. + // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('instagram'..) + if (!IsAtLeastiOSVersion(@"9.0")) { + if (![self canShareViaInstagram]) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + } + + NSString *message = [command.arguments objectAtIndex:0]; + // subject is not supported by the SLComposeViewController + NSArray *filenames = [command.arguments objectAtIndex:2]; + + // only use the first image (for now.. maybe we can share in a loop?) + UIImage *image = nil; + for (NSString *filename in filenames) { + image = [self getImage:filename]; + break; + } // NSData *imageObj = [NSData dataFromBase64String:objectAtIndex0]; - NSString *tmpDir = NSTemporaryDirectory(); - NSString *path = [tmpDir stringByAppendingPathComponent:@"instagram.igo"]; - [UIImageJPEGRepresentation(image, 1.0) writeToFile:path atomically:YES]; - - _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]]; - _documentInteractionController.delegate = self; - _documentInteractionController.UTI = @"com.instagram.exclusivegram"; - - if (message != (id)[NSNull null]) { - // no longer working, so .. - _documentInteractionController.annotation = @{@"InstagramCaption" : message}; - - // .. we put the message on the clipboard (you app can prompt the user to paste it) - UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; - [pasteboard setValue:message forPasteboardType:@"public.utf8-plain-text"]; - } - - // remember the command for the delegate method - _command = command; - - // test for #513 - dispatch_async(dispatch_get_main_queue(), ^(void){ - [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.webView animated:YES]; - }); -} - -- (void)shareViaWhatsApp:(CDVInvokedUrlCommand*)command { - - // on iOS9 canShareVia('whatsapp'..) will only work if whatsapp:// is whitelisted. - // If it's not, this method will ask permission to the user on iOS9 for opening the app, - // which is of course better than WhatsApp sharing not working at all because you forgot to whitelist it. - // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('whatsapp'..) - if (!IsAtLeastiOSVersion(@"9.0")) { - if (![self canShareViaWhatsApp]) { - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - } - - NSString *message = [command.arguments objectAtIndex:0]; - // subject is not supported by the SLComposeViewController - NSArray *filenames = [command.arguments objectAtIndex:2]; - NSString *urlString = [command.arguments objectAtIndex:3]; - NSString *abid = [command.arguments objectAtIndex:4]; - NSString *phone = [command.arguments objectAtIndex:5]; - - // only use the first image (for now.. maybe we can share in a loop?) - UIImage *image = nil; - for (NSString *filename in filenames) { - image = [self getImage:filename]; - break; - } - - // with WhatsApp, we can share an image OR text+url.. image wins if set - if (image != nil) { - NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/whatsAppTmp.jpg"]; - [UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES]; - _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]]; - _documentInteractionController.UTI = @"net.whatsapp.image"; + NSString *tmpDir = NSTemporaryDirectory(); + NSString *path = [tmpDir stringByAppendingPathComponent:@"instagram.igo"]; + [UIImageJPEGRepresentation(image, 1.0) writeToFile:path atomically:YES]; + + _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]]; _documentInteractionController.delegate = self; + _documentInteractionController.UTI = @"com.instagram.exclusivegram"; + + if (message != (id) [NSNull null]) { + // no longer working, so .. + _documentInteractionController.annotation = @{@"InstagramCaption": message}; + + // .. we put the message on the clipboard (you app can prompt the user to paste it) + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + [pasteboard setValue:message forPasteboardType:@"public.utf8-plain-text"]; + } + + // remember the command for the delegate method _command = command; - [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated: YES]; - } else { - // append an url to a message, if both are passed - NSString *shareString = @""; - if (message != (id)[NSNull null]) { - shareString = message; - } - if (urlString != (id)[NSNull null]) { - if ([shareString isEqual: @""]) { - shareString = urlString; - } else { - shareString = [NSString stringWithFormat:@"%@ %@", shareString, [urlString SSURLEncodedString]]; - } - } - NSString *encodedShareString = [shareString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - // also encode the '=' character - encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"=" withString:@"%3D"]; - encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"&" withString:@"%26"]; - NSString *abidString = @""; - if (abid != (id)[NSNull null]) { - abidString = [NSString stringWithFormat:@"abid=%@&", abid]; - } - NSString *phoneString = @""; - if (phone != (id)[NSNull null]) { - phoneString = [NSString stringWithFormat:@"phone=%@&", phone]; - } - NSString *encodedShareStringForWhatsApp = [NSString stringWithFormat:@"whatsapp://send?%@%@text=%@", abidString, phoneString, encodedShareString]; - - NSURL *whatsappURL = [NSURL URLWithString:encodedShareStringForWhatsApp]; - [[UIApplication sharedApplication] openURL: whatsappURL]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } + + // test for #513 + dispatch_async(dispatch_get_main_queue(), ^(void) { + [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.webView animated:YES]; + }); } -- (void)saveToPhotoAlbum:(CDVInvokedUrlCommand*)command { - self.command = command; - NSArray *filenames = [command.arguments objectAtIndex:0]; - [self.commandDelegate runInBackground:^{ - bool shared = false; - for (NSString* filename in filenames) { - UIImage* image = [self getImage:filename]; - if (image != nil) { - shared = true; - UIImageWriteToSavedPhotosAlbum(image, self, @selector(thisImage:wasSavedToPhotoAlbumWithError:contextInfo:), nil); - } +- (void)shareViaWhatsApp:(CDVInvokedUrlCommand *)command { + + // on iOS9 canShareVia('whatsapp'..) will only work if whatsapp:// is whitelisted. + // If it's not, this method will ask permission to the user on iOS9 for opening the app, + // which is of course better than WhatsApp sharing not working at all because you forgot to whitelist it. + // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('whatsapp'..) + if (!IsAtLeastiOSVersion(@"9.0")) { + if (![self canShareViaWhatsApp]) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } } - if (!shared) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no valid image was passed"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; + + NSString *message = [command.arguments objectAtIndex:0]; + // subject is not supported by the SLComposeViewController + NSArray *filenames = [command.arguments objectAtIndex:2]; + NSString *urlString = [command.arguments objectAtIndex:3]; + NSString *abid = [command.arguments objectAtIndex:4]; + NSString *phone = [command.arguments objectAtIndex:5]; + + // only use the first image (for now.. maybe we can share in a loop?) + ShareContent *content = nil; + for (NSString *filename in filenames) { + content = [self getShareContent:filename]; + break; + } + + // with WhatsApp, we can share an content (image, video, etc) OR text+url.. content wins if set + if (content != nil) { + _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[content getUrl]]; + _documentInteractionController.delegate = self; + if ([content getType] == VIDEO) { + _documentInteractionController.UTI = @"public.movie"; + } else if ([content getType] == IMAGE) { + _documentInteractionController.UTI = @"public.image"; + } else if ([content getType] == AUDIO) { + _documentInteractionController.UTI = @"public.audio"; + } + _command = command; + [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated:YES]; + } else { + // append an url to a message, if both are passed + NSString *shareString = @""; + if (message != (id) [NSNull null]) { + shareString = message; + } + if (urlString != (id) [NSNull null]) { + if ([shareString isEqual:@""]) { + shareString = urlString; + } else { + shareString = [NSString stringWithFormat:@"%@ %@", shareString, [urlString SSURLEncodedString]]; + } + } + NSString *encodedShareString = [shareString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + // also encode the '=' character + encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"=" withString:@"%3D"]; + encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"&" withString:@"%26"]; + NSString *abidString = @""; + if (abid != (id) [NSNull null]) { + abidString = [NSString stringWithFormat:@"abid=%@&", abid]; + } + NSString *phoneString = @""; + if (phone != (id) [NSNull null]) { + phoneString = [NSString stringWithFormat:@"phone=%@&", phone]; + } + NSString *encodedShareStringForWhatsApp = [NSString stringWithFormat:@"whatsapp://send?%@%@text=%@", abidString, phoneString, encodedShareString]; + + NSURL *whatsappURL = [NSURL URLWithString:encodedShareStringForWhatsApp]; + [[UIApplication sharedApplication] openURL:whatsappURL]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - }]; +} + +- (void)saveToPhotoAlbum:(CDVInvokedUrlCommand *)command { + self.command = command; + NSArray *filenames = [command.arguments objectAtIndex:0]; + [self.commandDelegate runInBackground:^{ + bool shared = false; + for (NSString *filename in filenames) { + UIImage *image = [self getImage:filename]; + if (image != nil) { + shared = true; + UIImageWriteToSavedPhotosAlbum(image, self, @selector(thisImage:wasSavedToPhotoAlbumWithError:contextInfo:), nil); + } + } + if (!shared) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no valid image was passed"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; + } + }]; } // called from saveToPhotoAlbum, note that we only send feedback for the first image that's being saved (not keeping the callback) // but since the UIImageWriteToSavedPhotosAlbum function is only called with valid images that should not be a problem -- (void)thisImage:(UIImage *)image wasSavedToPhotoAlbumWithError:(NSError *)error contextInfo:(void*)ctxInfo { - if (error) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.localizedDescription]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; - } else { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; - } -} - --(UIImage*)getImage: (NSString *)imageName { - UIImage *image = nil; - if (imageName != (id)[NSNull null]) { - if ([imageName hasPrefix:@"http"]) { - image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageName]]]; - } else if ([imageName hasPrefix:@"www/"]) { - image = [UIImage imageNamed:imageName]; - } else if ([imageName hasPrefix:@"file://"]) { - image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[NSURL URLWithString:imageName] path]]]; - } else if ([imageName hasPrefix:@"data:"]) { - // using a base64 encoded string - NSURL *imageURL = [NSURL URLWithString:imageName]; - NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; - image = [UIImage imageWithData:imageData]; - } else if ([imageName hasPrefix:@"assets-library://"]) { - // use assets-library - NSURL *imageURL = [NSURL URLWithString:imageName]; - NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; - image = [UIImage imageWithData:imageData]; +- (void)thisImage:(UIImage *)image wasSavedToPhotoAlbumWithError:(NSError *)error contextInfo:(void *)ctxInfo { + if (error) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.localizedDescription]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; } else { - // assume anywhere else, on the local filesystem - image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageName]]; - } - } - return image; -} - --(NSURL*)getFile: (NSString *)fileName { - NSURL *file = nil; - if (fileName != (id)[NSNull null]) { - NSRange rangeData = [fileName rangeOfString:@"data:"]; - if ([fileName hasPrefix:@"http"]) { - NSURL *url = [NSURL URLWithString:fileName]; - NSData *fileData = [NSData dataWithContentsOfURL:url]; - NSURLRequest *request = [NSURLRequest requestWithURL: url]; - NSHTTPURLResponse *response; - [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: nil]; - if ([response respondsToSelector:@selector(allHeaderFields)]) { - NSDictionary *dictionary = [response allHeaderFields]; - NSLog([dictionary description]); - NSString *name = dictionary[@"Content-Disposition"]; - if (name == nil){ - NSString *name = (NSString*)[[fileName componentsSeparatedByString: @"/"] lastObject]; - file = [NSURL fileURLWithPath:[self storeInFile:[name componentsSeparatedByString: @"?"][0] fileData:fileData]]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId]; + } +} + +- (NSObject *)getMedia:(NSString *)fileName { + UIImage *image = [self getImage:fileName]; + if (image != nil) + return image; + return [self getFile:fileName]; +} + +- (UIImage *)getImage:(NSString *)imageName { + UIImage *image = nil; + if (imageName != (id) [NSNull null]) { + if ([imageName hasPrefix:@"http"]) { + image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageName]]]; + } else if ([imageName hasPrefix:@"www/"]) { + image = [UIImage imageNamed:imageName]; + } else if ([imageName hasPrefix:@"file://"]) { + image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[NSURL URLWithString:imageName] path]]]; + } else if ([imageName hasPrefix:@"data:"]) { + // using a base64 encoded string + NSURL *imageURL = [NSURL URLWithString:imageName]; + NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + image = [UIImage imageWithData:imageData]; + } else if ([imageName hasPrefix:@"assets-library://"]) { + // use assets-library + NSURL *imageURL = [NSURL URLWithString:imageName]; + NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + image = [UIImage imageWithData:imageData]; } else { - file = [NSURL fileURLWithPath:[self storeInFile:[[name componentsSeparatedByString:@"="] lastObject] fileData:fileData]]; + // assume anywhere else, on the local filesystem + image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageName]]; } - } else { - NSString *name = (NSString*)[[fileName componentsSeparatedByString: @"/"] lastObject]; - file = [NSURL fileURLWithPath:[self storeInFile:[name componentsSeparatedByString: @"?"][0] fileData:fileData]]; - } - } else if ([fileName hasPrefix:@"www/"]) { - NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; - NSString *fullPath = [NSString stringWithFormat:@"%@/%@", bundlePath, fileName]; - file = [NSURL fileURLWithPath:fullPath]; - } else if ([fileName hasPrefix:@"file://"]) { - // stripping the first 6 chars, because the path should start with / instead of file:// - file = [NSURL fileURLWithPath:[fileName substringFromIndex:6]]; - } else if (rangeData.location != NSNotFound ){ - //If found "data:" - NSString *fileType = (NSString*)[[[fileName substringFromIndex:rangeData.location+rangeData.length] componentsSeparatedByString: @";"] objectAtIndex:0]; - - NSString* attachmentName; - //Find df anywhere in string - NSRange rangeDF = [fileName rangeOfString:@"df:"]; - //If not found fallback to default name - if (rangeDF.location == NSNotFound) { - attachmentName = @"attachment."; - attachmentName = [attachmentName stringByAppendingString:(NSString*)[[fileType componentsSeparatedByString: @"/"] lastObject]]; + } + return image; +} + +- (ShareContent *)getShareContent:(NSString *)fileName { + ShareContent *shareContent = [[ShareContent alloc] init]; + NSURL *file = [self getFile:fileName]; + [shareContent setUrl:file]; + return shareContent; +} + +- (NSURL *)getFile:(NSString *)fileName { + NSURL *file = nil; + if (fileName != (id) [NSNull null]) { + NSRange rangeData = [fileName rangeOfString:@"data:"]; + if ([fileName hasPrefix:@"http"]) { + NSURL *url = [NSURL URLWithString:fileName]; + NSData *fileData = [NSData dataWithContentsOfURL:url]; + NSURLRequest *request = [NSURLRequest requestWithURL:url]; + NSHTTPURLResponse *response; + [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; + if ([response respondsToSelector:@selector(allHeaderFields)]) { + NSDictionary *dictionary = [response allHeaderFields]; + NSLog([dictionary description]); + NSString *name = dictionary[@"Content-Disposition"]; + if (name == nil) { + NSString *name = (NSString *) [[fileName componentsSeparatedByString:@"/"] lastObject]; + file = [NSURL fileURLWithPath:[self storeInFile:[name componentsSeparatedByString:@"?"][0] fileData:fileData]]; + } else { + file = [NSURL fileURLWithPath:[self storeInFile:[[name componentsSeparatedByString:@"="] lastObject] fileData:fileData]]; + } + } else { + NSString *name = (NSString *) [[fileName componentsSeparatedByString:@"/"] lastObject]; + file = [NSURL fileURLWithPath:[self storeInFile:[name componentsSeparatedByString:@"?"][0] fileData:fileData]]; + } + } else if ([fileName hasPrefix:@"www/"]) { + NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; + NSString *fullPath = [NSString stringWithFormat:@"%@/%@", bundlePath, fileName]; + file = [NSURL fileURLWithPath:fullPath]; + } else if ([fileName hasPrefix:@"file://"]) { + // stripping the first 6 chars, because the path should start with / instead of file:// + file = [NSURL fileURLWithPath:[fileName substringFromIndex:6]]; + } else if (rangeData.location != NSNotFound) { + //If found "data:" + NSString *fileType = (NSString *) [[[fileName substringFromIndex:rangeData.location + rangeData.length] componentsSeparatedByString:@";"] objectAtIndex:0]; + + NSString *attachmentName; + //Find df anywhere in string + NSRange rangeDF = [fileName rangeOfString:@"df:"]; + //If not found fallback to default name + if (rangeDF.location == NSNotFound) { + attachmentName = @"attachment."; + attachmentName = [attachmentName stringByAppendingString:(NSString *) [[fileType componentsSeparatedByString:@"/"] lastObject]]; + } else { + //Found, apply name + attachmentName = (NSString *) [[[fileName substringFromIndex:rangeDF.location + rangeDF.length] componentsSeparatedByString:@";"] objectAtIndex:0]; + } + + + NSString *base64content = (NSString *) [[fileName componentsSeparatedByString:@","] lastObject]; + NSData *data = [SocialSharing dataFromBase64String:base64content]; + file = [NSURL fileURLWithPath:[self storeInFile:attachmentName fileData:data]]; + } else { - //Found, apply name - attachmentName = (NSString*)[[[fileName substringFromIndex:rangeDF.location+rangeDF.length] componentsSeparatedByString: @";"] objectAtIndex:0]; + // assume anywhere else, on the local filesystem + file = [NSURL fileURLWithPath:fileName]; } - - - NSString *base64content = (NSString*)[[fileName componentsSeparatedByString: @","] lastObject]; - NSData* data = [SocialSharing dataFromBase64String:base64content]; - file = [NSURL fileURLWithPath:[self storeInFile:attachmentName fileData:data]]; - - } else { - // assume anywhere else, on the local filesystem - file = [NSURL fileURLWithPath:fileName]; } - } - return file; + return file; } --(NSString*) storeInFile: (NSString*) fileName - fileData: (NSData*) fileData { - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsDirectory = [paths objectAtIndex:0]; - // remove filename wrapping quotes - NSString *filenameWithoutQuote = [fileName stringByReplacingOccurrencesOfString:@"'" withString:@""]; - NSString *filePath = [documentsDirectory stringByAppendingPathComponent:filenameWithoutQuote]; - [fileData writeToFile:filePath atomically:YES]; - _tempStoredFile = filePath; - return filePath; +- (NSString *)storeInFile:(NSString *)fileName + fileData:(NSData *)fileData { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + // remove filename wrapping quotes + NSString *filenameWithoutQuote = [fileName stringByReplacingOccurrencesOfString:@"'" withString:@""]; + NSString *filePath = [documentsDirectory stringByAppendingPathComponent:filenameWithoutQuote]; + [fileData writeToFile:filePath atomically:YES]; + _tempStoredFile = filePath; + return filePath; } -- (void) cleanupStoredFiles { - if (_tempStoredFile != nil) { - NSError *error; - [[NSFileManager defaultManager]removeItemAtPath:_tempStoredFile error:&error]; - } +- (void)cleanupStoredFiles { + if (_tempStoredFile != nil) { + NSError *error; + [[NSFileManager defaultManager] removeItemAtPath:_tempStoredFile error:&error]; + } } -+ (NSData*) dataFromBase64String:(NSString*)aString { - return [[NSData alloc] initWithBase64EncodedString:aString options:0]; ++ (NSData *)dataFromBase64String:(NSString *)aString { + return [[NSData alloc] initWithBase64EncodedString:aString options:0]; } #pragma mark - UIPopoverControllerDelegate methods - (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView **)view { - NSArray *comps = [[self getIPadPopupCoordinates] componentsSeparatedByString:@","]; - CGRect newRect = [self getPopupRectFromIPadPopupCoordinates:comps]; - rect->origin = newRect.origin; + NSArray *comps = [[self getIPadPopupCoordinates] componentsSeparatedByString:@","]; + CGRect newRect = [self getPopupRectFromIPadPopupCoordinates:comps]; + rect->origin = newRect.origin; } - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { - _popover = nil; + _popover = nil; } #pragma mark - UIDocumentInteractionControllerDelegate methods -- (void) documentInteractionController: (UIDocumentInteractionController *) controller willBeginSendingToApplication: (NSString *) application { - // note that the application actually contains the app bundle id which was picked (for whatsapp and instagram only) - NSLog(@"SocialSharing app selected: %@", application); +- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application { + // note that the application actually contains the app bundle id which was picked (for whatsapp and instagram only) + NSLog(@"SocialSharing app selected: %@", application); } -- (void) documentInteractionControllerDidDismissOpenInMenu: (UIDocumentInteractionController *) controller { - if (self.command != nil) { - CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:result callbackId: self.command.callbackId]; - } +- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller { + if (self.command != nil) { + CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self.commandDelegate sendPluginResult:result callbackId:self.command.callbackId]; + } } @end From 81ecf984867f4af2a90646318468b84e8c8c4a96 Mon Sep 17 00:00:00 2001 From: hudson Date: Wed, 23 Sep 2020 15:23:50 -0300 Subject: [PATCH 2/2] Correction in imports --- src/ios/ShareContent.m | 4 ++++ src/ios/SocialSharing.m | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ios/ShareContent.m b/src/ios/ShareContent.m index 9d72e35f..75a40bcf 100644 --- a/src/ios/ShareContent.m +++ b/src/ios/ShareContent.m @@ -1,3 +1,7 @@ +#import "ShareContent.h" +#import +#import + @implementation ShareContent { NSURL * _url; ContentType _type; diff --git a/src/ios/SocialSharing.m b/src/ios/SocialSharing.m index 3748ff3a..7aec07f3 100644 --- a/src/ios/SocialSharing.m +++ b/src/ios/SocialSharing.m @@ -1,6 +1,7 @@ #import "SocialSharing.h" #import "NSString+SSURLEncoding.h" #import "ShareContent.h" +#import "CustomSLComposeViewController.h" #import #import #import @@ -303,7 +304,7 @@ - (void)shareViaInternal:(CDVInvokedUrlCommand *)command NSString *urlString = [command.arguments objectAtIndex:3]; // boldly invoke the target app, because the phone will display a nice message asking to configure the app - SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:type]; + CustomSLComposeViewController *composeViewController = (CustomSLComposeViewController *)[CustomSLComposeViewController composeViewControllerForServiceType:type]; if (message != (id) [NSNull null]) { [composeViewController setInitialText:message]; }