It's been almost 2 days that i'm looking to find a solution to my problem but i wasn't successful , i want to share GIF (animated image) on Facebook, Twitter, Email, WhatsApp , using "UIActivityViewController".
This is my code :
NSURL *imagePath = [NSURL URLWithString:#"http://sth.gif"];
NSData *animatedGif = [NSData dataWithContentsOfURL:imagePath];
NSArray *sharingItems = [NSArray arrayWithObjects: animatedGif,stringToShare, nil];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
When i share in Email its animated and its working perfect , but in Twitter , Facebook , whatsApp Gifs are not animated and its like an image ...
I already read all Stack-overflow questions about the same problem Like this or this or this but its not working for me.
So far base on days research found out that :
TWITTER : For share a GIF on twitter had to use twitter API and create a multipart request to achieve the goal and its working very well.
FACEBOOK : I did share some GIF on Facebook using FACEBOOKSHAREKIT , but i don't know why sometimes Gifs are animated, sometimes not.
INSTAGRAM : To share gif on Instagram had to convert GIFS to MP4 (or any other video formats accepted by Instagram) then save it into camera roll then share it , It is little twisted but its working very well.
WHATSAPP : It not supporting GIF at all. READ THE UPDATE
To do all of this i couldn't use "UIActivityViewController" , so decided to create a custom share page. if anybody know something to add here , to help me and others please tell me (especially about Facebook).
Thanks in advance
UPDATE
WHATSAPP : Thanks to #AmmarShahid, as he mentioned in comments, Whatsapp now supports gif.
Encountered the similar problem and Googled a lot but still not a perfect solution, the best I came up is here:
Use UIActivityItemProvider and extend - (id)item {} for different UIActivityType:
Twitter: The default UIActivityViewController Twitter share doesn't support it yet which it will "scale down" it as a still JPG. However somehow it works for GIF less than 100kb (tested in iOS 9) and I don't know why. Therefore, I have to use SLRequest to upload the GIF as taught in here. When the SLRequest is done and return, dismiss the UIActivityViewController. The downside of that is no preview share sheet and users cannot type their own message anymore.
Facebook: It's actually much easier! Just upload the GIF to Giphy, then provide the Giphy URL to UIActivityViewController instead of the file contents, Facebook will recognize it and show the animated GIF
- (id)item
{
if ([self.activityType isEqualToString:UIActivityTypePostToFacebook]) {
// Upload to Giphy
...
return [NSURL URLWithString:giphyURL];
}
if ([self.activityType isEqualToString:UIActivityTypePostToTwitter]) {
// Use SLRequest to share instead
...
// Dismiss the UIActivityViewController (I am using Unity)
[UnityGetGLViewController() dismissViewControllerAnimated:NO completion: NULL];
return nil;
}
}
full code is in my GitHub, I am actually a iOS newb so some experts please correct me and the code if possible
// Share GIF File: WhatsApp
NSURL *imageUrl =[self.ImageArray objectAtIndex:currentPhotoIndex];
NSString *path=imageUrl.absoluteString;
NSArray *strings = [path componentsSeparatedByString:#"/"];
NSString *mygif=[strings objectAtIndex:strings.count-1];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dataPath = [documentsPath stringByAppendingPathComponent:#"/MrHRamani"];
NSString *filePath = [dataPath stringByAppendingPathComponent:mygif];
NSURL *urll=[NSURL fileURLWithPath:filePath];
NSLog(#"imag %#",imageUrl);
self.documentationInteractionController.delegate = self;
self.documentationInteractionController.UTI = #"net.whatsapp.image";
self.documentationInteractionController = [self setupControllerWithURL:urll usingDelegate:self];
[self.documentationInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
Related
I want to share PDF file with Evernote in iOS application.
Note: I have found the code of Evernote login from Evernote official website but didn't get any reference of sharing PDF from anywhere.
I have found solution of my above question :
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"pdf-sample" ofType:#"pdf"];
NSData *pdfFileData = [NSData dataWithContentsOfFile:filePath];
ENResource * resource = [[ENResource alloc] initWithData:pdfFileData mimeType:#"application/pdf" filename:#"pdf-sample.pdf"];
ENNote * note = [[ENNote alloc] init];
note.title = #"Costsfirst PDF file";
[note addResource:resource];
[[ENSession sharedSession] uploadNote:note notebook:nil completion:^(ENNoteRef *noteRef, NSError *uploadNoteError) {
NSString * message = nil;
if (noteRef) {
message = #"Pdf uploaded!";
} else {
message = #"Failed to upload.";
}
}];
Above code is working perfectly for me.
If I do understand your question then, to share PDF with Evernote from your iOS app, can be achieved via UIActivityViewController.
try this:
NSData *pdfFileData = [NSData dataWithContentsOfFile:pdfFilePath];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[#"Test", pdfFileData] applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
--- OR ---
NSString *str = [[NSBundle mainBundle] pathForResource:#"YourPdfFileName" ofType:#"pdf"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[#"Test", [NSURL fileURLWithPath:str]] applicationActivities:nil];
With the code above, You could scroll over on UIActivityViewController’s share section, and use other custom share extensions like Evernote.
You didn’t have to do a thing. As a user, just click the more button to show the ones you want in the share sheet. As a developer, you don’t have to do anything to your UIActivityViewController to show custom Share and Action Extensions.
Hope this may help you.
Regarding Evernote cloud sdk for iOS:
https://github.com/evernote/evernote-cloud-sdk-ios/blob/master/Getting_Started.md
This document covers getting set up with the Evernote Cloud SDK for iOS, some quick examples, and some discussion of the primary classes.
I am new to Programing, I've programed an iOS app which is almost completed, Now I want to integrate contents(Image, Text and URL) sharing capability to my app, I've achieved Facebook and Twitter Sharing functionality, But I am stuck at Instagram sharing functionality since two days.
I've studied lots of material(earlier asked question here StackOverFlow, also tried MGInstagram and few other third party API's) but all of those are outdated & not working on iOS9 & iOS10,
I tried to achieve some help from Instagram site but there too I am not cleared.
Can Anyone Define some easy way to integrate Instagram Sharing button code in my iOS app also to define authentication process from Instagram site clearly like as tokens & other permissions required for developers.
Thanks
As per your Desired question for iOS 9 and 10 So I am explaining for both.
I am using Instagram,s Standard Documentation API as defined in iPhone Hooks at Instagram
Step1:
open your info.plist file and add LSApplicationQueriesSchemes and add your URL schemes which you are going to call in your canOpenURL like this.
It is also defined in WWDC 2015 Session 703 by kitty scatter.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
</array>
It will open instargram app installed in your device.
note It'll never work in your simulator because of unavailability of required app.
Step2:
in your .h file where your #interface line ends add this <UIDocumentInteractionControllerDelegate> to the same #interface line
Step3:
add following code for sharing image in your instagram sharing button's action
// This is your Image you want to share. you can write
UIImage *image = imageView.image;
//Add this line of code instead of doing step One if you are at early version of iOS9 till iOS 9.2.3 but if you are using iOS9.5 or above like as iOS10 not use this line and do step1 instead of writing this line of code
NSURL *instagram = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagram]) {
//convert image into .png format.
NSData *imageData = UIImagePNGRepresentation(image);
//create instance of NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
//create an array and store result of our search for the documents directory in it
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//create NSString object, that holds our exact path to the documents directory
NSString *documentsDirectory = [paths objectAtIndex:0];
//add our image to the path
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"insta.igo"]];
//finally save the path (image)
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
CGRect rect = CGRectMake(0 ,0 , 0, 0);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndImageContext();
NSString *fileNameToSave = [NSString stringWithFormat:#"Documents/insta.igo"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:fileNameToSave];
NSLog(#"jpg path %#",jpgPath);
NSString *newJpgPath = [NSString stringWithFormat:#"file://%#",jpgPath];
NSLog(#"with File path %#",newJpgPath);
// NSURL *igImageHookFile = [[NSURL alloc]initFileURLWithPath:newJpgPath];
NSURL *igImageHookFile = [NSURL URLWithString:newJpgPath];
NSLog(#"url Path %#",igImageHookFile);
UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:igImageHookFile];
documentController.delegate = self;
[documentController setUTI:#"com.instagram.exclusivegram"];
[documentController presentOpenInMenuFromRect:rect inView:self.view animated:YES];
} else {
// NSLog (#"Instagram not found");
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Install Instagram"
message:#" Before Sharing to Instagram, Please Install Instagram app to your Device. "
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"Thanks" style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
Final Note:
Follow Step one if you are using iOS SDK 9.5 or above like 10. and to remove second line of code mentioned in third step. and in case you are using iOS 9 till 9.2.3 then no needs to do first step, you should follow second line of code of third step.
Hope it'll work smoothly like water flow. . . :)
This should open instagram on a device and share the photo onto Instagram.
- (IBAction)imageShareToInsta:(id)sender {
NSString *imagePath = [NSString stringWithFormat:#"%#/image.igo", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]];
[[NSFileManager defaultManager] removeItemAtPath:imagePath error:nil];
[UIImagePNGRepresentation(self.imageView.image) writeToFile:imagePath atomically:YES];
UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:imagePath]];
docController.delegate=self;
docController.UTI = #"com.instagram.exclusivegram";
[docController presentOpenInMenuFromRect:self.view.frame inView:self.view animated:YES];
}
Declare <UIDocumentInteractionControllerDelegate>in your ViewController.h file
Hope it helps you out.
I need to give my players an ability to post GIF replays ONLY to their Twitter accounts. I've managed to create a basic general sharing dialog but the problem is, I can't remove all irrelevant sharing options: Notes, Skype and etc. Long hours of fighting with iOS and no results. There are no activity types for the stuff I want to exclude, so adding it to "excludedActivityTypes" is impossible. Tweet Sheet didn't help either, it can't share GIFs.
Are there any other options, guys? Current implementation:
I want to do smth like this (just add FB to excluded activities):
If you are only wanting to allow sharing of the animated GIF to Twitter, it doesn't make much sense to use the UIActivityViewController to display the share sheet with only one option.
Why not just build your own using the SLComposeViewController? You have greater control over the UI and it's fewer button presses for the user. To do so, you can take a look at the sample code provided in this tutorial.
// Use this code :by. Ramani Hitesh iOS developer)
NSURL *imageUrl =[self.ImageArray objectAtIndex:currentPhotoIndex];
NSString *path=imageUrl.absoluteString;
NSArray *strings = [path componentsSeparatedByString:#"/"];
NSString *mygif=[strings objectAtIndex:strings.count-1];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dataPath = [documentsPath stringByAppendingPathComponent:#"/MrHRamani"];
NSString *filePath = [dataPath stringByAppendingPathComponent:mygif];
NSURL *urll=[NSURL fileURLWithPath:filePath];
NSLog(#"imag %#",imageUrl);
self.documentationInteractionController.delegate = self;
self.documentationInteractionController.UTI = #"net.whatsapp.image";
self.documentationInteractionController = [self setupControllerWithURL:urll usingDelegate:self];
[self.documentationInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
I've got a (for me) big problem.
I want to send a vcf-file with airdrop from my own app to another iOS device. I've got a NSData object, which i should convert to a vcf file, and this I should send with airdrop to another IOS device.
The NSData object works fine, i can send a vcc file with email, but with airdrop I left my limit.
I tried everything i found here in the forum and on developer.apple.com. But nothing works, I think the reason is, that i have no idea how too start the fix the problem.
Has anybody any idea how i can realize it?
THANKS
I believe this is roughly what you are looking for:
NSString *contactName = nil; // name of person in vcard
NSData *vcfData = nil; // vcard data
NSURL *fileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.vcf", contactName]]];
NSError *writeError;
if ([vcfData writeToURL:fileURL options:NSDataWritingAtomic error:&writeError]) {
NSArray *activityItems = #[fileURL];
UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
[self presentViewController:avc animated:YES completion:nil];
} else {
// failed, handle errors
}
If you still want to support providing NSData to some of the activities you will have to create some objects that conforms to UIActivityItemSource protocol and have some of them return nil where appropriate (see this SO for more details on that). You might find the AirDrop sample code project from Apple helpful too.
When I use UIDocumentInteractionController to allow users to share via Instagram, it does work, it brings up the option for "open with" and "Instagram" as one of the options... the problem is that it also displays many other apps like "Facebook" and "Twitter"...
Is there any way I can make it only give the option of opening in the instagram app?
Instagram claims there is a way to do this: http://instagram.com/developer/iphone-hooks/ but they mention this:
"Alternatively, if you want to show only Instagram in the application list (instead of Instagram plus any other public/jpeg-conforming apps) you can specify the extension class igo, which is of type com.instagram.exclusivegram."
but I honestly have no clue what this part means, "extension class igo"
My code:
UIImage *imageToUse = [UIImage imageNamed:#"imageToShare.png"];
NSString *documentDirectory=[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.ig"];
NSData *imageData=UIImagePNGRepresentation(imageToUse);
[imageData writeToFile:saveImagePath atomically:YES];
NSURL *imageURL=[NSURL fileURLWithPath:saveImagePath];
docController = [UIDocumentInteractionController interactionControllerWithURL:imageURL];
docController.delegate = self;
docController.annotation = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:#"This is the users caption that will be displayed in Instagram"], #"InstagramCaption", nil];
docController.UTI = #"com.instagram.exclusivegram";
[docController presentOpenInMenuFromRect:CGRectMake(1, 1, 1, 1) inView:self.view animated:YES];
Turns out to get the doc controller to only open in Instagram you just save your png or jpg file in format ".igo" file type extension, (Maybe stands for Instagram-Only?)
Changed the third line of code in my code to read this instead:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.igo"];
(With "igo")
and then it worked! :)
Lower version of iOS 13:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.igo"];
After iOS 13:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.ig"];