如何为纯文本实现 Open In 应用程序

Posted

技术标签:

【中文标题】如何为纯文本实现 Open In 应用程序【英文标题】:How to implement Open In apps for plain text 【发布时间】:2014-04-26 02:49:50 【问题描述】:

我想为用户提供点击“操作”按钮并弹出常用共享表的功能,其中应包括消息、Facebook 等图标右侧的其他应用程序 - 可以处理 .txt 文件的应用程序,或者只是一个NSString

我目前正在通过UIActivityViewController 显示一个共享表,它运行良好,但它不包括列表中的其他应用程序。通过阅读其他 SO 问题,我得出结论,如果您改用 UIDocumentInteractionController,则只有可能出现其他应用程序。我考虑在临时目录中创建一个 .txt 文件来共享该文件(而不仅仅是共享 NSString),但是当我点击“共享”按钮时只显示邮件(无副本)。 [请注意,如果我在真实设备而不是模拟器上运行它,则会出现除 Mail 以外的更多应用程序,并且还会出现 AirDrop。] 当我点击 Mail 时,应用程序崩溃:无法获取 URL 数据:操作无法完成. (Cocoa 错误 260。)我创建/检索 .txt 文件的方式有问题。

我的问题是:

为什么我的代码在尝试共享 .txt 文件时会导致崩溃? 如何让复制选项显示在与包含其他应用程序的共享表相同的共享表中?

总结一下:我需要一个共享表,其中包括:复制、AirDrop、消息、邮件、Facebook、Twitter、Pages、Dropbox 等,以获取简单的文本字符串。谢谢!

以下代码行位于我的 IBAction 共享按钮点击功能中: UIActivityViewController 方法:

UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:@[self.myUITextField.text] applicationActivities:nil];
[self presentViewController:activityView animated:YES completion:nil];

结果:

UIDocumentInteractionController 方法:

NSString *fileName = [NSString stringWithFormat:@"%@mytextfile.txt", NSTemporaryDirectory()];
[self.myUITextField.text writeToFile:fileName
                          atomically:NO
                            encoding:NSStringEncodingConversionAllowLossy
                               error:nil];
NSURL *textFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"mytextfile.txt"]];

UIDocumentInteractionController *documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:textFileURL];
[documentInteractionController presentOptionsMenuFromBarButtonItem:sender animated:YES];

结果(如果我在真实设备上运行,将显示更多应用和 AirDrop):

我想要获得的示例 - 减去底部的 3 个额外选项:

如果由于某种原因我无法获得带有字符串(而不是照片)的上述屏幕截图,我愿意按照 Dropbox 的方式实现它。他们在底部添加了一个“打开方式”按钮,该按钮显示了一个仅显示其他应用程序的不同工作表。请注意,我仍然需要原始工作表上的“复制”选项。

【问题讨论】:

到底出现了什么?屏幕截图可能会有所帮助。 仅邮件。我意识到模拟器没有其他应用程序,但它仍然应该像使用活动视图控制器一样具有 Copy。 那么,您是否检查过是否出现了其他已安装的应用程序?还是您的问题是关于让 Copy 出现? 我还没有。它在点击邮件时崩溃 - 我的 URL 有问题,它找不到文件,并且没有我需要的副本。 %@ 后面是否缺少斜杠? 【参考方案1】:

问题 1:为什么我的代码会导致崩溃

根据Foundation Constants Reference 文档,Cocoa 错误 260 是一个NSFileReadNoSuchFileError。查看您的代码,我看到文件创建可能失败的唯一方法是 self.myUITextFieldnil

我建议你先检查一下。如果属性不是nil,则检查writeToFile:atomically:encoding:error:是否返回错误。


问题 2:如何让复制选项出现

首先,给控制器分配一个委托:

documentInteractionController.delegate = self;

然后实现以下两个委托方法:

- (BOOL) documentInteractionController:(UIDocumentInteractionController*)controller canPerformAction:(SEL)action

  if (@selector(copy:) == action)
    return YES;
  else
    return NO;


- (BOOL) documentInteractionController:(UIDocumentInteractionController*)controller performAction:(SEL)action

  if (@selector(copy:) != action)
    return NO;
  // Perform the copy: action
  return YES;

这两种方法自 ios 6 以来都被标记为已弃用,但它们似乎在 iOS 7 中仍然有效。不幸的是,如果没有这两种方法,我不知道如何实现 copy: 操作 - Apple 也不知道,或者看起来如此对我来说,因为他们不提供替代品,官方Document Interaction Programming Topics for iOS 文档仍然很高兴地引用了这些方法,但没有表明它们已被弃用。

不管怎样,下面是第二个委托方法的简单但完整的实现:

- (BOOL) documentInteractionController:(UIDocumentInteractionController*)controller performAction:(SEL)action

  if (@selector(copy:) != action)
    return NO;

  NSStringEncoding usedEncoding;
  NSError* error;
  NSString* fileContent = [NSString stringWithContentsOfURL:controller.URL
                                               usedEncoding:&usedEncoding
                                                      error:&error];
  UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
  [pasteboard setString:fileContent];
  return YES;

【讨论】:

谢谢,有一个错误 - 我通过将编码更改为 NSUTF8StringEncoding 来修复它。现在可以了,我发现 documentInteractionController 确实会自动添加 Copy 按钮。但我决定走一条不同的路,像 Dropbox 那样做。

以上是关于如何为纯文本实现 Open In 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Open in... 自定义文件类型适用于 iOS 5、6 和 7,但不适用于 iOS 4

如何为 ACTION_OPEN_DOCUMENT 意图实现自定义 MIME 类型?

如何用程序实现将word文件转换成txt纯文本文件

如何为 Camellia 密码提供正确的密钥并在 Java 中进行加密

如何为 Cloudwatch 创建自定义文本格式化程序?

如何为 iphone 应用程序设置动画以逐字显示文本?