Динамично генерирующие предварительные просмотры

Если можно с готовностью преобразовать документ из его собственного формата в надлежащий формат Беглого взгляда, генератор может выполнить то преобразование для предварительных просмотров того документа. Такое преобразование является самым полезным для текстовых форматов Беглого взгляда (HTML, RTF и простой текст), но можно также генерировать предварительные просмотры в любом формате, поддерживаемом Беглым взглядом; например, при преобразовании документа, представляющего 3D модель в формат DAE Collada Беглый взгляд может вывести на экран интерфейс предварительного просмотра разрешение модели масштабироваться и поворачиваться. (Обратите внимание на то, что графический контекст остается самым эффективным способом предоставить данные двухмерного изображения Беглому взгляду; посмотрите Миниатюры Получения и Предварительные просмотры В Графическом Контексте для подробных данных.)

Создание Текстовых Представлений Динамично обсуждает один способ динамично создать текстовый предварительный просмотр (в этом случае, RTF).

Если можно генерировать данные HTML для предварительного просмотра, можно также включать присоединения для таких элементов как изображения, таблицы стилей CSS и сценарии JavaScript. Можно использовать эти элементы для обеспечения подробных разметок и интерактивности в интерфейсе предварительного просмотра Беглого взгляда; Генерация Обогащенного HTML описывает этот подход.

Создание текстовых представлений динамично

Динамическая генерация предварительного просмотра может быть полезна для типов документов, содержащих текстовую информацию в нечеловекочитаемом формате. Примером этого вида типа документа является формат локализованных строк, используемый XCode (см. Строковые ресурсы Локализации для получения дополнительной информации). Документ локализованных строк может храниться в двоичном файле или формате XML, таким образом, генератор Беглого взгляда может интерпретировать эти форматы и генерировать предварительный просмотр RTF, использующий шрифты и цвета для создания содержания документа простым читать. Пример кода в Перечислении 6-1 иллюстрирует один способ создать такой предварительный просмотр.

QLPreviewRequestSetDataRepresentation вызов функции является самой важной частью этого кода. Генератор обеспечивает два параметра для этой функции — данные RTF для предварительного просмотра и константы UTI, указывающей, какой собственный Беглый взгляд объект данных содержит.

Перечисление 6-1  , Генерирующее предварительный просмотр в RTF-формате

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{
    @autoreleasepool {
 
        // Load the strings dictionary from the URL
        NSDictionary *localizationDict = [NSDictionary dictionaryWithContentsOfURL:(__bridge NSURL *)url];
        if (!localizationDict) return noErr;
 
        // The above might have taken some time, so before proceeding make sure the user didn't cancel the request
        if (QLPreviewRequestIsCancelled(preview)) return noErr;
 
        // Set up for producing attributed string output
        NSDictionary *keyAttrs = @{ NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Oblique" size:11.0],
                                    NSForegroundColorAttributeName : [NSColor grayColor] };
        NSDictionary *valAttrs = @{ NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:18.0] };
        NSAttributedString *newline = [[NSAttributedString alloc] initWithString:@"\n"];
        NSMutableAttributedString *output = [[NSMutableAttributedString alloc] init];
 
        // Iterate through pairs in the dictionary to add formatted output
        [localizationDict enumerateKeysAndObjectsUsingBlock:^(id key, id val, BOOL *stop) {
            NSAttributedString *keyString = [[NSAttributedString alloc] initWithString:key attributes:keyAttrs];
            NSAttributedString *valString = [[NSAttributedString alloc] initWithString:val attributes:valAttrs];
            [output appendAttributedString:valString];
            [output appendAttributedString:newline];
            [output appendAttributedString:keyString];
            [output appendAttributedString:newline];
            [output appendAttributedString:newline];
        }];
 
        // Get RTF representation of the attributed string
        NSData *rtfData = [output RTFFromRange:NSMakeRange(0, output.length) documentAttributes:nil];
 
        // Pass preview data to QuickLook
        QLPreviewRequestSetDataRepresentation(preview,
                                              (__bridge CFDataRef)rtfData,
                                              kUTTypeRTF,
                                              NULL);
    }
    return noErr;
}

Генерация обогащенного HTML

Обычно полезный, но немного более сложный подход к генерации предварительного просмотра динамично должен создать HTML. Этот подход идеально подходит для приложений, которые не являются прежде всего текстовыми или графическими в природе, такими как приложения, пользовательский интерфейс документа которых является комбинацией текста и графики или приложений, выводящих на экран их данные документа в пользовательском интерфейсе, состоящем из табличных представлений, текста и полей формы, маркированных флажков, и т.д.

Можно также использовать этот подход для преобразования документа, хранившего в одном или более нечеловекочитаемых форматах для более удобного для пользователя дисплея предварительного просмотра. Пример кода в Перечислении 6-2 иллюстрирует такое использование при помощи Фундаментальных классов, чтобы считать файл списка свойств и произвести отформатированное представление для предварительного просмотра. Это также создает словарь свойств, который будет пасоваться назад к Беглому взгляду в вызове к QLPreviewRequestSetDataRepresentation; свойства в этом словаре определяют данные HTML и присоединения, связанные с теми данными.

Перечисление 6-2  , Генерирующее предварительный просмотр, сочинило данных HTML плюс присоединение

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{
    @autoreleasepool {
 
        // Load the property list from the URL
        NSURL *nsurl = (__bridge NSURL *)url;
        NSData *data = [NSData dataWithContentsOfURL:nsurl];
        if (!data) return noErr;
        id plist = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:nil];
        if (!plist) return noErr;
 
        // The above might have taken some time, so before proceeding make sure the user didn't cancel the request
        if (QLPreviewRequestIsCancelled(preview)) return noErr;
 
        // Set up the object that creates the HTML preview
        HTMLPreviewBuilder *builder = [[HTMLPreviewBuilder alloc] init];
        builder.title = [nsurl lastPathComponent];
        builder.stylesheet = [NSURL URLWithString:@"cid:plistStylesheet.css"];
 
        // Generate a preview for this plist and retrieve it as a string
        // (Begin recursive preview generation by wrapping the plist's top level object in a dictionary)
        NSString *html = [builder previewForDictionary:@{ @"Root" : plist }];
 
        // Load a CSS stylesheet to attach to the HTML
        NSBundle *bundle = [NSBundle bundleForClass:[HTMLPreviewBuilder class]];
        NSURL *cssFile = [bundle URLForResource:@"plistStylesheet" withExtension:@"css"];
        NSData *cssData = [NSData dataWithContentsOfURL:cssFile];
 
        // Put metadata and attachment in a dictionary
        NSDictionary *properties = @{ // properties for the HTML data
                                     (__bridge NSString *)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8",
                                     (__bridge NSString *)kQLPreviewPropertyMIMETypeKey : @"text/html",
                                     // properties for attaching the CSS stylesheet
                                     (__bridge NSString *)kQLPreviewPropertyAttachmentsKey : @{
                                             @"plistStylesheet.css" : @{
                                                     (__bridge NSString *)kQLPreviewPropertyMIMETypeKey : @"text/css",
                                                     (__bridge NSString *)kQLPreviewPropertyAttachmentDataKey: cssData,
                                                     },
                                             },
                                     };
 
        // Pass preview data and metadata/attachment dictionary to QuickLook
        QLPreviewRequestSetDataRepresentation(preview,
                                              (__bridge CFDataRef)[html dataUsingEncoding:NSUTF8StringEncoding],
                                              kUTTypeHTML,
                                              (__bridge CFDictionaryRef)properties);
    }
    return noErr;
}

Существует несколько вещей, достойных специального уведомления в Перечислении 6-2:

Когда генератор вызывает QLPreviewRequestSetDataRepresentation это передает в данных HTML (в указанном кодировании), словарь свойств и постоянное содержимое HTML идентификации UTI. С HTML и коллекцией словарей свойств таким образом, WebKit может загрузить HTML и, когда это анализирует его, загрузите присоединения в веб-представление.