Сохранение предварительных просмотров и миниатюр в документе

Как один подход для обеспечения миниатюры и данных предварительного просмотра к Беглому взгляду, приложение может хранить те данные как часть данных документа. Генератор может тогда получить доступ к нему и возвратить его Беглому взгляду в вызове к QLThumbnailRequestSetImageWithData или QLPreviewRequestSetDataRepresentation. Этот подход разрешает быстрое время отклика для генератора, но за счет большего файла документа.

Чтобы проиллюстрировать, как Ваш генератор мог бы обеспечить предварительные просмотры и миниатюры с помощью этого подхода, следующие списки показывают модификации коду для приложения Эскиза, пишущего изображение миниатюр как часть данных документа. Перечисление 7-1 показывает, как Вы могли бы определить свойство NSDocument разделите на подклассы для содержания данных изображения.

  Проект Эскиза перечисления 7-1 в качестве примера: добавление свойства миниатюры

@interface SKTDrawDocument : NSDocument {
    @private
    NSMutableArray *_graphics;
    // ...other instance variables here...
    NSData *_thumbnail;
}
// ...existing methods here...
- (NSData *)thumbnail;

Реализуйте thumbnail метод доступа возвратить изображение миниатюр. К NSDocument метод, подготавливающий данные документа к выписыванию к файлу (dataOfType:error:) добавляются строки кода в Перечислении 7-2, обозначенном «новыми» метками.

  Проект Эскиза перечисления 7-2 в качестве примера: включая миниатюру с данными документа

static NSString *SKTThumbnailImageKey = @"SketchThumbnail";                   // new
 
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
    NSData *data,;
    NSArray *graphics = [self graphics];
    NSPrintInfo *printInfo = [self printInfo];
    NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
    BOOL useTypeConformance = [workspace respondsToSelector:@selector(type:conformsToType:)];
 
    if ((useTypeConformance && [workspace type:SKTDrawDocumentNewTypeName conformsToType:typeName])
        || [typeName isEqualToString:SKTDrawDocumentOldTypeName]) {
        NSData *tiffRep;                                                     // new
        NSMutableDictionary *properties = [NSMutableDictionary dictionary];
 
        [properties setObject:[NSNumber numberWithInt:SKTDrawDocumentCurrentVersion] forKey:SKTDrawDocumentVersionKey];
        [properties setObject:[SKTGraphic propertiesWithGraphics:graphics] forKey:SKTDrawDocumentGraphicsKey];
        [properties setObject:[NSArchiver archivedDataWithRootObject:printInfo] forKey:SKTDrawDocumentPrintInfoKey];
        tiffRep = [self TIFFDataWithGraphics:graphics error:outError];        // new
        [properties setObject:tiffRep forKey:SKTThumbnailImageKey];           // new
        data = [NSPropertyListSerialization dataFromPropertyList:properties
                                                          format:NSPropertyListBinaryFormat_v1_0
                                                errorDescription:NULL];
    } else if ((useTypeConformance && [workspace type:(__bridge NSString *)kUTTypePDF conformsToType:typeName])
               || [typeName isEqualToString:NSPDFPboardType]) {
        data = [SKTRenderingView pdfDataWithGraphics:graphics];
    } else {
        NSParameterAssert((useTypeConformance && [workspace type:(__bridge NSString *)kUTTypeTIFF conformsToType:typeName])
                          || [typeName isEqualToString:NSTIFFPboardType]);
        data = [SKTRenderingView tiffDataWithGraphics:graphics error:outError];
    }
    return data;
}

В соответствии NSDocument метод для чтения данных документа въезжает задним ходом (readFromData:ofType:error:) «распакуйте» миниатюру из словаря свойств документа:

_thumbnail = [properties objectForKey:SKTThumbnailImageKey];

Теперь реализация генератора для Эскиза является простым вопросом доступа к данным изображения миниатюр и передачи его к Беглому взгляду в вызове к QLThumbnailRequestSetImageWithData, как показано в Перечислении 7-3. (Для предварительных просмотров соответствующая функция QLPreviewRequestSetDataRepresentation.)

Перечисление 7-3  Возвращая сохраненное изображение миниатюр Беглому взгляду

OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
    @autoreleasepool {
        SKTDrawDocument* document = [[SKTDrawDocument alloc] init];
        if (![document readFromURL:(__bridge NSURL *)url
                            ofType:(__bridge NSString *)contentTypeUTI]) {
            return noErr;
        }
        if ([document respondsToSelector:@selector(thumbnail)]) {  // runtime verification
            NSData *tiffData = [document thumbnail];
            if (tiffData != nil) {
                NSDictionary *props = [NSDictionary dictionaryWithObject:@"public.tiff" forKey:(__bridge NSString *)kCGImageSourceTypeIdentifierHint];
                QLThumbnailRequestSetImageWithData(thumbnail, (__bridge CFDataRef)tiffData, (__bridge CFDictionaryRef)props);
                return noErr;
            }
        }
        NSSize canvasSize = [document canvasSize];
        CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, *(CGSize *)&canvasSize, false, NULL);
        if (cgContext) {
            NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)cgContext flipped:YES];
            if (context) {
                [document drawDocumentInContext:context];
            }
            QLThumbnailRequestFlushContext(thumbnail, cgContext);
            CFRelease(cgContext);
        }
    }
    return noErr;
}

В вызове к QLThumbnailRequestSetImageWithData, генератор указывает формат изображения к Беглому взгляду с kCGImageSourceTypeIdentifierHint свойство. Обратите внимание на то, что этот пример проверяет, реализует ли класс объекта документа thumbnail метод доступа (для исключения предыдущих версий приложения) и, если так, это проверяет, возвращаются ли данные миниатюры. Если это не, это составляет изображение миниатюр в предоставленном беглым взглядом графическом контексте.