【问题标题】:Other apps paste the HTML rather than the text version of our pasteboard data in iOS 5其他应用在 iOS 5 中粘贴 HTML 而不是我们粘贴板数据的文​​本版本
【发布时间】:2011-10-17 21:19:13
【问题描述】:

我们有一个现有的应用程序,允许用户将文本复制到粘贴板。如果可能,我们会将 HTML 和纯文本都放在剪贴板上,因为我们不知道用户可能会粘贴到哪个其他应用程序中,并且希望同时提供格式化 (HTML) 和未格式化的数据。

此功能在 iOS 3 和 4 中运行良好。但一旦用户安装 iOS 5,当他们将文本从我们的应用程序粘贴到任何其他应用程序时,其他应用程序会获取 HTML 文本但将其视为纯文本。因此,如果他们选择并复制 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 下运行的同一个应用程序会获取纯文本?”

【问题讨论】:

    标签: iphone ipad ios5 uipasteboard uti


    【解决方案1】:

    对于那些在家玩的人来说,这是我们发现的答案。

    “public.utf8-plain-text”历来是在将包含未格式化文本的 NSString 放入粘贴板时使用的正确 UTI。内置控件在“粘贴”操作期间所有请求和使用此版本的粘贴板内容(适用于 5 之前的 iOS 版本)。如果您只在粘贴板中放置“public.plain-text”或“public.text”文本,内置控件会完全忽略它,说粘贴板是空的(不给您“粘贴”选项)。

    在 iOS 5 中,发生了一些变化,当内置控件在上述情况下请求纯文本时,它们将获得“public.html”文本。

    对于 iOS 5,您必须使用“public.text”而不是“public.plain-text”或“public.utf8-plain-text”,即使后两者可以说更正确,而前完全有用。

    由于早期的 iO​​S 版本忽略“public.text”,我们的解决方案是将所有三个版本都放在粘贴板上:“public.text”和“public.utf8-plain-text”都会为您提供纯文本和“ public.html" 将为您提供 HTML 文本。这似乎可以同时满足 iOS 4 和 5 的要求,而无需在代码中进行明确的 iOS 版本测试,代价是字典中多了一个条目。

    Apple 的孩子们又一次失败了。

    为 2016 年和 iOS 8/9 编辑

    自从我发布这个问题以来,我一直在尝试一劳永逸地解决这个问题。每当我进行谷歌搜索时,我总是会回到这个问题。

    在某个地方,iOS 引入了“网络存档”概念,用于将 HTML 放在粘贴板上。它在任何地方都没有很好的记录。我找到了一个答案here,它早于我的问题,所以这有点令人沮丧,但它确实有效。我已对其进行了更新,以利用 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];
    

    【讨论】:

    • 感谢您的信息。希望您已将此记录为 Apple 的错误。
    • 在我的调查中,只要不包含 public.html,utf8-plain-text 仍然有效。我假设这是因为视图现在要求 public.text,并且它们得到了一些子类型,其中 public.html 是其中之一。我假设包含一个 public.text 只是比 public.html 更高的优先级。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    相关资源
    最近更新 更多