[英]How to send a PDF file using UIActivityViewController
I'm trying to send a PDF using a UIActivityViewController
.我正在尝试使用UIActivityViewController
发送 PDF。 So far everything works fine using a fairly basic approach but the one issue I have is that when I select the send by mail option, the PDF's file name is Attachment-1
rather than Calculation.PDF
which is the name that I give the file.到目前为止,使用相当基本的方法一切正常,但我遇到的一个问题是,当我选择通过邮件发送选项时,PDF 的文件名是Attachment-1
而不是Calculation.PDF
,这是我给文件的名称。
I don't mind too much the change in title, but the lack of a .pdf extension does seem to cause a problem when sending the file to people with Windows PC's and I'd like to fix that.我不太介意标题的变化,但是在将文件发送给使用 Windows PC 的人时,缺少 .pdf 扩展名似乎确实会导致问题,我想解决这个问题。
I've had a look at: Control file name of UIImage send with UIActivityViewController我看过: Control file name of UIImage send with UIActivityViewController
But can't see an equivalent method to:但看不到等效的方法:
[mailComposer addAttachmentData: UIImagePNGRepresentation(viewImage) mimeType:@"" fileName:@"myImage.png"];
that will work with a PDF file.这将适用于 PDF 文件。 Is this something that is not fixable without customization or is there a simple solution to this problem?这是没有定制就无法修复的东西,还是有一个简单的解决方案来解决这个问题?
try this尝试这个
NSData *pdfData = [NSData dataWithContentsOfFile:pdfFilePath];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"Test", pdfData] applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
and also并且
NSString *str = [[NSBundle mainBundle] pathForResource:@"AppDistributionGuide" ofType:@"pdf"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"Test", [NSURL fileURLWithPath:str]] applicationActivities:nil];
Swift迅速
let url = NSURL.fileURLWithPath(fileName)
let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
presentViewController(activityViewController, animated: true, completion: nil)
Here I attached code.I just added thread handling in to present "activityViewController" because of this viewcontroller present before load actual data.在这里我附上了代码。我只是添加了线程处理来呈现“activityViewController”,因为在加载实际数据之前存在这个视图控制器。
let url = NSURLfileURL(withPath:fileName)
let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
DispatchQueue.main.async {
self.present(activityViewController, animated: true, completion: nil)
}
Above listing about Swift is deprecated in Swift 3上面关于 Swift 的列表在 Swift 3 中已被弃用
let url = NSURL.fileURL(withPath: fileName)
let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
present(activityViewController,
animated: true,
completion: nil)
For Objective-C tested code to share PDF用于通过 Objective-C 测试的代码共享 PDF
- (void)downloadPDFfile:(NSString *)fileName withFileURL:(NSString *)shareURL {
dispatch_async(dispatch_get_main_queue(), ^ {
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentDir stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@",[self generateName:fileName withFiletype:@"pdf"]]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:shareURL]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Download Error:%@",error.description);
} else if (data && error == nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[data writeToFile:filePath atomically:YES];
[self shareFile:fileName withFilepath:filePath];
});
}
}];
[task resume];
});
}
-(void)shareFile:(NSString*)withfileName withFilepath:(NSString*)filePath {
NSMutableArray *items = [NSMutableArray array];
if (filePath) {
[items addObject:[NSURL fileURLWithPath:filePath]];
}
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[activityViewController setValue:withfileName forKey:@"subject"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
activityViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popPC = activityViewController.popoverPresentationController;
popPC.sourceView = self.view;
CGRect sourceRext = CGRectZero;
sourceRext.origin = CGPointMake(self.view.frame.size.width-30, 0);
popPC.sourceRect = sourceRext;
popPC.permittedArrowDirections = UIPopoverArrowDirectionDown;
}
[activityViewController setCompletionWithItemsHandler:
^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
}];
[self presentViewController:activityViewController animated:YES completion:nil];
}
-(NSString*)generateName:(NSString*)title withFiletype:(NSString*)type {
NSString *subject = [title stringByReplacingOccurrencesOfString:@" " withString:@"_"];
subject = [NSString stringWithFormat:@"%@.%@",subject,type];
return subject;
}
call function like below调用函数如下
[self downloadPDFfile:@"yourFileName" withFileURL:shareURL];
For Swift 3对于 Swift 3
You have to have a URL
array with the path of the PDF you want to send.您必须有一个包含要发送的 PDF 路径的URL
数组。
let urlArray = [pdfPath1, pdfPath2]
Then create an UIActivityViewController
:然后创建一个UIActivityViewController
:
let activityController = UIActivityViewController(activityItems: urlArray, applicationActivities: nil)
If you are using a UIBarButtonItem
to make that action, you can implement this to prevent an error on iPad:如果您使用UIBarButtonItem
来执行该操作,您可以实施此操作以防止在 iPad 上出现错误:
if let popover = activityController.popoverPresentationController {
popover.barButtonItem = self.barButtonItem
}
Finally you have to present the activityController
:最后,您必须呈现activityController
:
self.present(activityController, animated: true, completion: nil)
The reply by Muruganandham K is simple and quite elegant. Muruganandham K 的回复简单而优雅。 However, it doesn't work in iOS 9. In order to make it work, if you remove the @[@"Test"
and just pass the pdfData, an attachment is made.但是,它在 iOS 9 中不起作用。为了使其工作,如果您删除@[@"Test"
并只传递 pdfData,则会生成一个附件。
NSData *pdfData = [NSData dataWithContentsOfFile:pdfFilePath];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:pdfData applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
May be try this..可以试试这个..
#define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
// Validate PDF using NSData
- (BOOL)isValidePDF:(NSData *)pdfData {
BOOL isPDF = false;
if (pdfData.length >= 1024 ) {
int startMetaCount = 4, endMetaCount = 5;
// check pdf data is the NSData with embedded %PDF & %%EOF
NSData *startPDFData = [NSData dataWithBytes:"%PDF" length:startMetaCount];
NSData *endPDFData = [NSData dataWithBytes:"%%EOF" length:endMetaCount];
// startPDFData, endPDFData data are the NSData with embedded in pdfData
NSRange startRange = [pdfData rangeOfData:startPDFData options:0 range:NSMakeRange(0, 1024)];
NSRange endRange = [pdfData rangeOfData:endPDFData options:0 range:NSMakeRange(0, pdfData.length)];
if (startRange.location != NSNotFound && startRange.length == startMetaCount && endRange.location != NSNotFound && endRange.length == endMetaCount ) {
// This assumes the checkstartPDFData doesn't have a specific range in file pdf data
isPDF = true;
} else {
isPDF = false;
}
}
return isPDF;
}
// Download PDF file in asynchronous way and validate pdf file formate.
- (void)downloadPDFfile:(NSString *) fileName withFileURL:(NSString *) url {
NSString *filePath = @"";
dispatch_async(dispatch_get_main_queue(), ^ {
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
filePath = [documentDir stringByAppendingPathComponent:[NSString stringWithFormat:@"/Attachments/%@",[self generateName:fileName withFiletype:@"pdf"]]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(@"Download Error:%@",error.description);
} else if (data && error == nil) {
bool checkPdfFormat = [self isValidePDF:data];
if (checkPdfFormat) {
//saving is done on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[data writeToFile:filePath atomically:YES];
NSURL *url = [NSURL fileURLWithPath:filePath];
[self triggerShare:fileName withFilepath:filePath];
});
}
}
}];
});
}
// Trigger default share and print functionality using UIActivityViewController
-(void) triggerShare:(NSString*)fileName withFilepath:(NSString*)filePath {
* Set this available field on the activity controller */
NSMutableArray *items = [NSMutableArray array];
if (filePath) {
[items addObject:[NSURL fileURLWithPath:filePath]];
}
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[activityViewController setValue:fileName forKey:@"subject"]; // Set the mail subject.
if (IS_IPAD) {
activityViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popPC = activityViewController.popoverPresentationController;
popPC.sourceView = self.view;
CGRect sourceRext = CGRectZero;
sourceRext.origin = CGPointMake(self.view.frame.size.width-30, 0 ); // I have share button in navigation bar. ;)
popPC.sourceRect = sourceRext;
popPC.permittedArrowDirections = UIPopoverArrowDirectionUp;
}
[activityViewController setCompletionWithItemsHandler:
^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
}];
[self presentViewController:activityViewController animated:YES completion:nil];
}
-(NSString*) generateName:(NSString*)title withFiletype:(NSString*)type {
NSString *subject = [title stringByReplacingOccurrencesOfString:@" " withString:@"_"];
subject = [NSString stringWithFormat:@"%@.%@",subject,type];
return subject;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.