It successfully redirects to the Whatsapp app.There is no preview frame and when tapped Send, an error messages pops up "This video could not be sent. Please choose a different video.
Here is my code.
- (void)shareVideo {
NSLog(#"[WhatsAppShare] sharing video");
//NSString *nativePath = [[NSString alloc] initWithCString:path encoding:NSASCIIStringEncoding];
NSString *nativePath=[[NSBundle mainBundle] pathForResource:#"video" ofType:#"mp4"];
// Save video to path in documents directory
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/whatsAppTmp.wam"];
if([[NSFileManager defaultManager] fileExistsAtPath:savePath]){
if([[NSFileManager defaultManager] removeItemAtPath:savePath error:nil]){
[self shareVideoAtNativePath:nativePath SavePath:savePath];
}
} else {
[self shareVideoAtNativePath:nativePath SavePath:savePath];
}}
- (void)shareVideoAtNativePath:(NSString*)nativePath SavePath:(NSString*)savePath{
NSError*error;
BOOL isSuccess=[[NSFileManager defaultManager] copyItemAtPath:nativePath toPath:savePath error:&error];
if(isSuccess){
// Create interaction controller
self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
self.documentInteractionController.UTI = #"net.whatsapp.movie";
self.documentInteractionController.delegate = self;
[self.documentInteractionController presentOpenInMenuFromRect:CGRectMake(0, 0, 1, 1)
inView:[self view]
animated:YES];
} else{
NSLog(#"error %#", error);
}
}
We have observed the exact same problem. Everything was working until a recent update of WhatsApp. This is probably a bug on WhatsApp side.
Here is a workaround for this problem:
Do not use a wam file, use the mp4 file directly. So in your case, just call
[self shareVideoAtNativePath:nativePath SavePath:nativePath];
Change the UTI to public Mpeg4:
self.documentInteractionController.UTI = #"public.mpeg-4";
This seems to have solved our issue. However, there is a drawback that, the share dialog now contains many other apps/services that can open mp4 files.
We've faced the exact same issue.
The official .wam format brings up only WhatsApp in the share dialog, but fails to forward the video.
Using .m4v format is working for us. A few more options are displayed along with WhatsApp (Open in WhatsApp is the option we want). We are displaying an alert saying "Please select Whatsapp on the next screen" before sending user to the share dialog.
File format: m4v
UTI: net.whatsapp.movie
Please refer to the working code below:
UIDocumentInteractionController *documentInteractionController;
-----
-----
- (void)shareVideoViaWhatsApp:(NSURL*)url{
// Creating temp video to share specifically on whatsapp.
NSString *cachesFolder = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat:#"video.m4v"]];
NSURL *file = [NSURL fileURLWithPath:cachesFolder];
[[NSData dataWithContentsOfURL:url] writeToURL:file options:NSDataWritingAtomic error:nil];
documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL: file ];
documentInteractionController.UTI = #"net.whatsapp.movie";
documentInteractionController.delegate = self;
[documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
// In code Use share GIF and Video for WhatsApp....
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/whatsAppTmp.wam"];
savePath = [[NSBundle mainBundle] pathForResource:#"Movie" ofType:#"m4v"];
_documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:_videourl];
_documentInteractionController.UTI = #"net.whatsapp.movie";
_documentInteractionController.delegate = (id)self;
[_documentInteractionController presentOpenInMenuFromRect:CGRectMake(0, 0, 0, 0) inView:self.view animated: YES];
Related
I am trying to upload a video to Whatsapp with an ALAsset URL, but it is loading the video when I share it using UIActivityViewController
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:self.videoURL resultBlock:^(ALAsset *asset) {
NSArray *objectsToShare = #[asset.defaultRepresentation.url];
FrodoInstagramActivity *instagramActivity = [[FrodoInstagramActivity alloc] init];
UIActivityViewController *activityVC = [[UIActivityViewController alloc]
initWithActivityItems:objectsToShare applicationActivities:#[instagramActivity]];
[self presentViewController:activityVC animated:YES completion:nil];
} failureBlock:nil];
Try this noh, "Movie" Your video which saved to local directory from video asset.
NSString * savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/whatsAppTmp.wam"];
savePath = [[NSBundle mainBundle] pathForResource:#"Movie" ofType:#"m4v"];
_documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
_documentInteractionController.UTI = #"net.whatsapp.movie";
_documentInteractionController.delegate = (id)self;
[_documentInteractionController presentOpenInMenuFromRect:CGRectMake(0, 0, 0, 0) inView:self.view animated: YES];
Save your asset locally, and get the local URL. Pass that URL path on the above code. Let's see.
Dont create each file locally for each video, just use the same file name for all videos and replace videos. And delete the video from local, after successfully uploaded. This might help.
I have also face this problem with sharing the link on whatsapp.
In whatsapp sharing was restrit to number of characters.
Please share url and text with maximum 150 characters.
then say what happen.
happy coding :)
I need to have Facebook and WhatsApp as sharing options for my image. I've already implemented UIActivityViewController, where i can share via Facebook and UIDocumentInteractionController where i can share via WhatsApp. I don't know how to merge these things.
UIActivityViewController:
UIActivityViewController *activityViewContoller = [[UIActivityViewController alloc]
initWithActivityItems:#[#"Test", image] applicationActivities:nil];
[self presentViewController:activityViewContoller animated:YES completion:nil];
UIDocumentInteractionController:
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/whatsAppTmp.wai"];
[UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES];
_documentInteractionController = [UIDocumentInteractionController
interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
_documentInteractionController.UTI = #"net.whatsapp.image";
_documentInteractionController.delegate = self;
[_documentInteractionController presentOpenInMenuFromRect:CGRectZero
inView:self.view animated:YES];
I want to have both of them in one popover, however I have no idea how to achieve it. Any tip please?
I've checked out StackOverFlow question 1, but it doesn't help me at all. My file is .wai (for WhatsApp) so when i try to send it via FB file is unable to open. Also it shows all options, while i want only 2(FB+WhatsApp) to be visible. Following the StackOverFlow question 2 I can show only FB (working one, because i set normal image) but can't add WhatsApp (no .wai file, i don't know what to do with UTI). Is there any way to solve this issue?
To change type of file:
- (void)share {
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/tmptmpimg.jpg"];
[UIImageJPEGRepresentation(_img, 1.0) writeToFile:path atomically:YES];
_documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
_documentInteractionController.delegate = self;
[_documentInteractionController presentOptionsMenuFromRect:CGRectZero inView:self.view animated:YES];
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
if ([self isWhatsApplication:application]) {
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/tmptmpimg.wai"];
[UIImageJPEGRepresentation(_img, 1.0) writeToFile:savePath atomically:YES];
controller.URL = [NSURL fileURLWithPath:savePath];
controller.UTI = #"net.whatsapp.image";
}
}
- (BOOL)isWhatsApplication:(NSString *)application {
if ([application rangeOfString:#"whats"].location == NSNotFound) { // unfortunately, no other way...
return NO;
} else {
return YES;
}
}
This way we can use all options- Facebook, Twitter and custom WhatsApp.
The problem with showing only selected options is still not solved, but it's the minor one.
To exclude non-desired sharing options (the second part of your question), assuming your UIActivityViewController object is called activityController, set the excludedActivityTypes property, like so:
activityController.excludedActivityTypes = #[UIActivityTypeAssignToContact,
UIActivityTypePrint,
UIActivityTypeAddToReadingList,
UIActivityTypeAirDrop];
Thanks to a couple other posts here , I've successfully be able to use the Instagram iPhone hooks to open Instagram and present it with a photo successfully from my application.
(I've made my ViewController class a delegate of UIDocumentInteractionController, and alloc/init'ed a nonatomic/retain property of UIDocumentInteractionController...
However, the key that I put into my NSDictionary that I place in the document controller annotation property will not seem to carry over to Instagram - the caption area is just empty.
How do I deal with this?
Here is my method:
- (void) uploadImageToInstagram:(UIImage *)imageToUpload {
NSLog(#"postToInstagramInBackground");
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
// Upscale to 612x612
imageToUpload = [self upscaleImage:imageToUpload];
// Get JPG + IGO Format
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/generate.igo"];
[UIImageJPEGRepresentation(imageToUpload, 1.0) writeToFile:savePath atomically:YES];
// Paths
NSURL *imageURL = [NSURL fileURLWithPath:savePath];
NSURL *igImageHookFile = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:#"file://%#",savePath]];
// Setup DocController
self.docController.UTI = #"com.instagram.photo";
self.docController = [self setupControllerWithURL:igImageHookFile usingDelegate:self];
self.docController.annotation = [NSDictionary dictionaryWithObject:#"MyApp" forKey:self.caption.text];
[self.docController setURL:imageURL];
[self.docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES ];
}
else {
NSLog(#"Instagram not installed in this device!\nTo share image please install Instagram.");
}
}
There are a few methods that are called here that I haven't included, one that upscales the image to make sure its 612x612, and one setups the file url for the document controller.
Proper syntax should be
self.docController.annotation = [NSDictionary dictionaryWithObject:self.caption.text forKey:#"InstagramCaption"];
I'm sending an email, with a PDF attachment, while using UIDocumentInteractionController, like this:
I start by showing the PDF file
-(void)showPDFFile
{
NSURL *url = [NSURL fileURLWithPath:_filePath];
if (url) {
_documentInteractionController =
[UIDocumentInteractionController interactionControllerWithURL:url];
[_documentInteractionController setDelegate: self];
[_documentInteractionController presentPreviewAnimated:YES];
}
}
- (UIDocumentInteractionController *)setupControllerWithURL:(NSURL *)fileURL
usingDelegate:(id <UIDocumentInteractionControllerDelegate>)interactionDelegate {
UIDocumentInteractionController *interactionController =
[UIDocumentInteractionController interactionControllerWithURL: fileURL];
[interactionController setDelegate: interactionDelegate];
return interactionController;
}
When the PDF file is shown, the user clicks the "Export" option and the iOS's "Open with" view appears.
Clicking the email now opens a View Controller ready to send an email.
How would I set the To: CC/BCC and Subject fields programatically?
Thank you!
You can assign the mail's subject by using the UIDocumentInteractionController name property:
_documentInteractionController.name = #"My custom mail subject";
Unfortunately this is the only attribute I've figured out that can be configured via UIDocumentInteractionController.
Unfortunately Florians answer didn't work for me. I had to copy the file locally and then set the URL to the local file. Setting the name only changed the title on the preview, not the filename or subject in the email.
i.e.
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* err = nil;
NSString* newPath = [appDocumentsFolder stringByAppendingPathComponent:name];
if (![fileManager copyItemAtPath:[[NSURL URLWithString:path] path] toPath:newPath error:&err]) {
// handle error
}
NSURL *fileURL = [NSURL fileURLWithPath:newPath];
_controller = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
This is what I'm trying to do:
Get a .pdf from external URL
Save it into my local disk
Display it in a WebView
Allow the user to move the .pdf to another app who can read .pdf
Everything from 1 to 3 works fine. But nothing is moved/shared to/with other apps. I can't understand what I'm doing wrong. This is what I'm doing.
How I save the pdf in the Documents folder (viewDidLoad):
// to save the pdf into local file system (tempString is the pdf url)
NSData *pdfData = [[NSData alloc]
initWithContentsOfURL:[NSURL URLWithString:tempString]];
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath stringByAppendingPathComponent:#"myPDF.pdf"];
[pdfData writeToFile:filePAth atomically:YES];
// to populate the WebView
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url2];
[my_web_view setUserInteractionEnabled:YES];
//[editoriale_view setDelegate:self];
[my_web_view loadRequest:requestObj];
In my viewDidLoad() function I create a button to allow the user to open a list of apps who can read .pdf files:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self
action:#selector(show_Button)];
And here's my show_Button function:
-(void)show_Button {
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath
stringByAppendingPathComponent:#"myPDF.pdf"];
NSLog(#"filePath = %#", filePAth);
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSLog(#"url2 = %#", url2);
UIDocumentInteractionController *docContr = [UIDocumentInteractionController
interactionControllerWithURL:url2];
[docContr presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
When I try this on my device everything works fine until I tap on one of the icons in the list (i.e. the iBooks one). Then the app closes (it doesn't crash, it simply closes).
Here's what the console prints for the two logs I put in the show_Button function:
1. filePath = /Users/[MY_USER]/Library/Application Support/iPhone
Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
2. url2 = file://localhost/Users/[MY_USER]/Library/Application%20Support/
iPhone%20Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
Anyone wants to try to make me understand what I'm doing wrong? I'm using Xcode 4.6. I browsed my iPhone app file system with a third-party software and the file "MyPDF.pdf" actually IS in the Documents" folder, and that's clear because the WebView is correctly populated.
Change CGRectZero to self.view.bounds when you display the document controller.
Solved. I had not implemented the UIDocumentenInteractionController delegate in the .h file. Now I have and everything works fine. Thank you to #trojanfoe for the useful hint.