Другие приложения вставляют HTML, а не текстовую версию наших данных в iOS 5 - PullRequest
3 голосов
/ 18 октября 2011

У нас есть приложение, которое позволяет пользователю копировать текст в монтажный картон. Когда это возможно, мы помещаем в буфер обмена как 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, получает простой текст?»

1 Ответ

6 голосов
/ 19 октября 2011

Для тех из вас, кто играет дома, вот ответ, который мы обнаружили.

"public.utf8-plain-text" исторически был правильным UTI для использования при помещении строки NSString, содержащей неформатированный текст, в монтажную область. Встроенные элементы управления контролируют все запросы и используют эту версию содержимого монтажной панели во время операций «вставки» (для версий 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 в коде за счет еще одной записи в словаре.

Еще один сбой для детей в Apple.

РЕДАКТИРОВАТЬ на 2016 год и iOS 8/9

Я пытался решить эту проблему раз и навсегда с тех пор, как опубликовал этот вопрос. Всякий раз, когда я делаю поиск в Google, я всегда возвращаюсь к этому вопросу.

Где-то в линейке iOS появилась концепция «веб-архива» для размещения HTML на монтажной панели. Это нигде не документировано. Я нашел ответ здесь , который предшествовал моему вопросу, так что это немного расстраивает, но это работает. Я обновил его, чтобы использовать преимущества встроенной кодировки base64 в более поздних версиях iOS. Это выглядит примерно так:

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];
...