【问题标题】:How to send a PDF file using UIActivityViewController如何使用 UIActivityViewController 发送 PDF 文件
【发布时间】:2013-03-24 19:06:21
【问题描述】:

我正在尝试使用UIActivityViewController 发送 PDF。到目前为止,使用一种相当基本的方法一切正常,但我遇到的一个问题是,当我选择通过邮件发送选项时,PDF 的文件名是Attachment-1,而不是Calculation.PDF,这是我给文件的名称。

我不太介意标题的更改,但是在将文件发送给使用 Windows PC 的人时,缺少 .pdf 扩展名似乎确实会导致问题,我想解决这个问题。

我看过: Control file name of UIImage send with UIActivityViewController

但看不到等效的方法:

[mailComposer addAttachmentData: UIImagePNGRepresentation(viewImage) mimeType:@"" fileName:@"myImage.png"];

这将适用于 PDF 文件。这是没有定制就无法解决的问题,还是有解决此问题的简单方法?

【问题讨论】:

标签: objective-c swift ios6 uiactivityviewcontroller


【解决方案1】:

试试这个

NSData *pdfData = [NSData dataWithContentsOfFile:pdfFilePath];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"Test", pdfData] applicationActivities:nil];

[self presentViewController:activityViewController animated:YES completion:nil];

还有

NSString *str = [[NSBundle mainBundle] pathForResource:@"AppDistributionGuide" ofType:@"pdf"];   
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"Test", [NSURL fileURLWithPath:str]] applicationActivities:nil]; 

【讨论】:

  • @iTroyd23,我尝试了你的建议,但我无法设置附件的标题。那么,您能描述一下如何设置附件的标题(例如 myPdf.pdf)
  • 只是说我都试过了,NSURL 最适合我的 XML 文件。
【解决方案2】:

斯威夫特

let url = NSURL.fileURLWithPath(fileName)

let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
        
presentViewController(activityViewController, animated: true, completion: nil)

【讨论】:

    【解决方案3】:

    斯威夫特 4.0

    在这里我附加了代码。我只是添加了线程处理来呈现“activityViewController”,因为这个视图控制器在加载实际数据之前存在。

    let url = NSURLfileURL(withPath:fileName)
    
    let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
    
    DispatchQueue.main.async {
                
        self.present(activityViewController, animated: true, completion: nil)
    }
    

    【讨论】:

      【解决方案4】:

      以上关于 Swift 的列表在 Swift 3 中已弃用

      let url = NSURL.fileURL(withPath: fileName)
      
      let activityViewController = UIActivityViewController(activityItems: [url] , applicationActivities: nil)
      
      present(activityViewController,
          animated: true,
          completion: nil)
      

      【讨论】:

        【解决方案5】:

        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;
        }
        

        如下调用函数

        [self downloadPDFfile:@"yourFileName" withFileURL:shareURL];
        

        【讨论】:

          【解决方案6】:

          对于 Swift 3

          您必须有一个 URL 数组,其中包含您要发送的 PDF 的路径。

          let urlArray = [pdfPath1, pdfPath2]
          

          然后创建一个UIActivityViewController:

          let activityController = UIActivityViewController(activityItems: urlArray, applicationActivities: nil)
          

          如果您使用UIBarButtonItem 执行该操作,您可以实施此操作以防止 iPad 上出现错误:

          if let popover = activityController.popoverPresentationController {
             popover.barButtonItem = self.barButtonItem
          }
          

          最后你必须提交activityController

          self.present(activityController, animated: true, completion: nil)
          

          【讨论】:

            【解决方案7】:

            Muruganandham K 的回复简单而优雅。但是,它在 iOS 9 中不起作用。为了使它起作用,如果您删除 @[@"Test" 并仅传递 pdfData,则会生成一个附件。

            NSData *pdfData = [NSData dataWithContentsOfFile:pdfFilePath];
            UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:pdfData applicationActivities:nil];
            
            [self presentViewController:activityViewController animated:YES completion:nil];
            

            【讨论】:

              【解决方案8】:

              可以试试这个..

                  #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;
                  }
              

              【讨论】:

                猜你喜欢
                • 2013-03-06
                • 2014-04-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-01-13
                • 2020-08-05
                • 1970-01-01
                相关资源
                最近更新 更多