其他应用在iOS 5中复制我们粘贴板数据的时候会复制HTML而不是纯文本版本。

3
我们有一个现有的应用程序,允许用户将文本复制到剪贴板。在可能的情况下,我们将HTML和纯文本都放在剪贴板上,因为我们不知道用户可能要粘贴到哪个其他应用程序中,想要提供格式化(HTML)和未格式化数据。
这个功能在iOS 3和4中运行得很好。但是,一旦用户安装了iOS 5,在他们从我们的应用程序中粘贴文本到任何其他应用程序时,其他应用程序会获得HTML文本,但将其视为纯文本。因此,如果他们选择并复制H1标题,当他们粘贴到其他应用程序时,而不是看到“This is a Heading”,他们会看到“<h1>This is a Heading</h1>”。
请注意,这是使用现有代码在iOS 3和4中正常工作的情况下。在iOS 3、4和5之间,我们的代码没有任何更改。
为了完整起见,这里是我们用于将文本放在剪贴板上的代码,仅提供一个简单的字符串作为参考:
NSString * plainText = @"A Big Heading\r\nA regular paragraph.";
NSString * htmlText = @"<h1>A Big Heading</h1><p>A regular paragraph.</p>";
UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
pasteboard.items = [NSArray arrayWithObject:
    [NSDictionary dictionaryWithObjectsAndKeys:
        plainText, @"public.utf8-plain-text", htmlText, @"public.html", nil]];

显然,我的问题是,“为什么在请求纯文本时,iOS 5的应用程序会得到HTML文本,而在运行相同的应用程序的iOS 4下会得到纯文本?”

1个回答

6
对于在家玩的人,这是我们发现的答案。
在将包含未格式化文本的NSString放入剪贴板时,“public.utf8-plain-text”历来是正确的UTI。内置控件在其“粘贴”操作期间请求并使用此版本的剪贴板内容(适用于iOS 5之前的版本)。如果你只将“public.plain-text”或“public.text”文本放入剪贴板中,内置控件会完全忽略它,并说剪贴板为空(不给你“粘贴”选项)。
在iOS 5中,当内置控件在上述情况下请求纯文本时,它们将获得“public.html”文本。
对于iOS 5,您必须使用“public.text”而不是“public.plain-text”或“public.utf8-plain-text”,尽管后两者可以说更正确,但前者太模糊而无法使用。
由于早期的iOS版本忽略了“public.text”,我们的解决方案是将所有三个版本都放在剪贴板上:“public.text”和“public.utf8-plain-text”都将为您提供纯文本,“public.html”将为您提供HTML文本。这似乎可以同时满足iOS 4和5,而无需在代码中放置显式的iOS版本测试,但需要一个更多的字典条目。
苹果公司又失败了。
2016年和iOS 8/9的编辑
自从我发布了这个问题以来,我一直在试图解决这个问题。每当我进行谷歌搜索时,我总是回到这个问题。
在某个地方,iOS引入了一个“Web存档”概念,用于将HTML放入剪贴板。它没有得到很好的记录。我在这里找到了一个答案,这比我的问题还要令人沮丧,但它确实有效。我已经更新了它,以利用后来版本的iOS中内置的base64编码。它大致是这样的:
NSMutableDictionary * contents = [NSMutableDictionary dictionaryWithCapacity:6];
NSString * htmlText = @"<h1>A Heading</h1><p>A paragraph.</p>"
//... put other formats in the dictionary, then...
NSData * data = [htmlText dataUsingEncoding:NSUTF8StringEncoding];
NSString * base64encodedString = [data base64EncodedStringWithOptions:0];
NSString * webArchiveString = [NSString stringWithFormat:
    @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
    "<plist version=\"1.0\">"
    "<dict>"
    "<key>WebMainResource</key>"
    "<dict>"
    "<key>WebResourceData</key>"
    "<data>%@</data>"
    "<key>WebResourceFrameName</key>"
    "<string></string>"
    "<key>WebResourceMIMEType</key>"
    "<string>text/html</string>"
    "<key>WebResourceTextEncodingName</key>"
    "<string>UTF-8</string>"
    "<key>WebResourceURL</key>"
    "<string>about:blank</string>"
    "</dict>"
    "</dict>"
    "</plist>", base64encodedString];
[contents setObject:webArchiveString forKey:@"Apple Web Archive pasteboard type"];
UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
pasteboard.items = [NSArray arrayWithObject:contents];

谢谢提供信息。希望你已经在苹果反馈系统中记录了这个 bug。 - Robotic Cat
1
在我的调查中,只要你不包括public.html,utf8-plain-text仍然可以使用。我假设这是因为视图现在正在请求public.text,而它们会得到一些子类型,其中public.html是其中之一。我假设包括public.text只是比public.html具有更高的优先级。 - Jesse Rusak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接