Пользовательские данные

Чтобы использоваться с областью монтажа, объект должен соответствовать NSPasteboardWriting и/или NSPasteboardReading протоколы. Можно заставить собственные объекты соответствовать этим протоколам, или можно использовать экземпляры NSPasteboardItem содержать пользовательские данные.

Обзор

Любой объект, что Вы ставите область монтажа, должен соответствовать NSPasteboardWriting протокол; для получения экземпляра объекта от области монтажа это должно принять NSPasteboardReading протокол. Несколько из общих классов Набора Основы и Приложения реализуют оба из этих протоколов, включая NSString, NSImage, NSURL, NSColor, NSAttributedString, и NSPasteboardItem.

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

Пользовательский класс

Для примеров, следующих, рассмотрите простой класс модели, представляющий закладку, поскольку Вы могли бы найти в веб-браузере:

@interface Bookmark : NSObject <NSCoding, NSPasteboardWriting, NSPasteboardReading> {
}
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *notes;
@property (nonatomic, retain) NSDate *date;
@property (nonatomic, retain) NSURL *url;
@property (nonatomic, retain) NSColor *color;
@end

Заметьте, что класс принимает NSCoding протокол так, чтобы это могло быть заархивировано и разархивировано.

Запись

Для поддержки записи в область монтажа класс должен соответствовать NSPasteboardWriting протокол. Это имеет три метода — один из которых является дополнительным — как описано ниже. Область монтажа отправляет эти сообщения в Ваш объект, когда Вы добавляете свой объект к области монтажа, так, чтобы это могло определить, какие типы данных это будет содержать и получить первое представление данных Вашего объекта. Если Ваш объект обеспечивает многократные представления, последний метод может быть вызван дополнительные времена.

- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard

Этот метод возвращает массив UTIs для типов данных, которые Ваш объект может записать в область монтажа.

Порядок в массиве является порядком, в котором типы должны быть добавлены к области монтажа — это важно как, только первый тип записан первоначально, другим предоставлены лениво (см. Обещанные Данные).

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

- (NSPasteboardWritingOptions)writingOptionsForType:(NSString *)type pasteboard:(NSPasteboard *)pasteboard

Этот метод является дополнительным. Это возвращает опции для записи данных типа к области монтажа.

Единственная опция, в настоящее время поддерживаемая, «обещана». Можно использовать это, если Вы хотите настроить поведение — например, гарантировать, что только обещан один определенный тип.

- (id)pasteboardPropertyListForType:(NSString *)type

Этот метод возвращает надлежащее объектное представление списка свойств Вашего объекта для указанного типа.

В большинстве случаев Вы просто реализуете эти два требуемых метода —writableTypesForPasteboard: и pasteboardPropertyListForType:.

В примере класса Закладки Вы могли реализовать writableTypesForPasteboard: следующим образом:

- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard {
    static NSArray *writableTypes = nil;
 
    if (!writableTypes) {
        writableTypes = [[NSArray alloc] initWithObjects:BOOKMARK_UTI,
    (NSString *)kUTTypeURL, NSPasteboardTypeString, nil];
    }
    return writableTypes;
}

Эта реализация игнорирует тип области монтажа, однако Вы могли бы принять решение возвратиться, различные типы для говорят, генерал и для области монтажа перетаскивания.

Вы могли реализовать pasteboardPropertyListForType: следующим образом:

- (id)pasteboardPropertyListForType:(NSString *)type {
 
    if ([type isEqualToString:BOOKMARK_UTI]) {
        return [NSKeyedArchiver archivedDataWithRootObject:self];
    }
 
    if ([type isEqualToString:(NSString *)kUTTypeURL]) {
        return [url pasteboardPropertyListForType:(NSString *)kUTTypeURL];
    }
 
    if ([type isEqualToString:NSPasteboardTypeString]) {
        return [NSString stringWithFormat:@"<a href=\"%@\">%@</a>",
    [url absoluteString], title];
    }
 
    return nil;
}

В примере метод возвращает любого NSData или NSString объект. Область монтажа принимает значения данных непосредственно, и автоматически преобразовывает строку в надлежащее представление данных. Если бы метод возвратил какой-либо другой тип списка свойств, то область монтажа автоматически преобразовала бы его в надлежащее представление данных.

Чтение

Для поддержки чтения от области монтажа класс должен соответствовать NSPasteboardReading протокол. Это имеет три метода, два из которых являются дополнительными.

+ (NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard

Этот метод класса возвращает массив UTIs для типов данных, которые Ваш объект может считать из области монтажа.

Метод обеспечивает параметр области монтажа так, чтобы можно было возвратиться для различных массивов для различных областей монтажа. Как с чтением, Вы могли бы поместить различные типы данных на общую область монтажа, чем Вы делаете на области монтажа перетаскивания, или Вы могли бы поставить те же типы данных, но в различном порядке.

+ (NSPasteboardReadingOptions)readingOptionsForType:(NSString *)type pasteboard:(NSPasteboard *)pasteboard

Этот метод класса является дополнительным. Это позволяет Вам указывать опции для чтения от области монтажа.

Опции выражены с помощью a NSPasteboardReadingOptions битовое поле. Можно указать, что соответствующие данные должны быть считаны как один из:

  • NSData объект (NSPasteboardReadingAsData)

    Это просто возвращает данные области монтажа как есть.

  • Строка (NSPasteboardReadingAsString)

    Данные области монтажа возвращаются как экземпляр NSString.

  • Список свойств (NSPasteboardReadingAsPropertyList)

    Данные по области монтажа не сериализируются как список свойств.

  • Архив (NSPasteboardReadingAsKeyedArchive)

    Данные по области монтажа обрабатываются как включенный архив.

- (id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type

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

Важный: Этот метод является дополнительным потому что: если Ваша реализация readableTypesForPasteboard: возвраты просто единственный тип и тот тип используют NSPasteboardReadingAsKeyedArchive чтение опции, тогда initWithCoder: вызывается вместо этого метода.

Объект списка свойств NSData для того типа на области монтажа, но путем указания NSPasteboardReading опция для типа, данные могут быть автоматически получены как список строк или список свойств.

В примере класса Закладки Вы могли реализовать протокол следующим образом

Во-первых, readableTypesForPasteboard: указывает, что можно инициализировать Закладку с помощью собственного типа и URL:

+ (NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard {
 
    static NSArray *readableTypes = nil;
    if (!readableTypes) {
        readableTypes = [[NSArray alloc] initWithObjects:BOOKMARK_UTI, (NSString *)kUTTypeURL, nil];
    }
    return readableTypes;
}

Затем, в этом случае обеспечьте реализацию readingOptionsForType:pasteboard: чтобы указать, что, если тип является Вашим пользовательским типом, Вы только хотите обработать данные как включенный архив, и если тип является типом URL тогда, поддерживают те же опции как NSURL.

+ (NSPasteboardReadingOptions)readingOptionsForType:(NSString *)type pasteboard:(NSPasteboard *)pboard {
    if ([type isEqualToString:BOOKMARK_UTI]) {
        /*
         This means you don't need to implement code for this
         type from initWithPasteboardPropertyList:ofType:
        */
        return NSPasteboardReadingAsKeyedArchive;
    }
    else if ([type isEqualToString: (NSString *)kUTTypeURL]) {
        return [NSURL readingOptionsForType:type pasteboard:pboard];
    }
    return 0;
}

Наконец, реализация initWithPasteboardPropertyList:ofType: следующим образом:

- (id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type {
 
    if (self = [self init]) {
        if ([type isEqualToString:(NSString *)kUTTypeURL]) {
            [url release];
            url = [[NSURL alloc] initWithPasteboardPropertyList:propertyList ofType:type];
            [title release];
            title = [[url absoluteString] retain];
        } else {
            [self release];
            return nil;
        }
    }
    return self;
}

Уведомление две вещи:

  1. Вызовы метода определяемый инициализатор, в этом случае init.

  2. Метод не тестирует на пользовательский тип Закладки. Вспомните это readableTypesForPasteboard: возвращенный просто единственный тип и это readingOptionsForType:pasteboard: указанный NSPasteboardReadingAsKeyedArchive как единственная опция чтения; таким образом для пользовательского типа Закладки initWithCoder: вместо вызывают initWithPasteboardPropertyList:ofType:.

NSPasteboardItem

Иногда Вы хотите записать элементы в область монтажа, но у Вас нет удобного интерфейсного объекта, или можно хотеть предоставить данные в распространенном формате, но только по требованию. Например, можно хотеть быть в состоянии обеспечить строку как приписанную строку, простую строку, или как табличный текст, откуда табличный текст отформатирован по-другому простой строки (таким образом, Вы не можете только записать приписанную строку непосредственно в область монтажа).

Для этих ситуаций можно использовать NSPasteboardItem объекты. В целом, NSPasteboardItem объекты предоставляют Вам тонкозернистое управление тем, что Вы могли бы поставить область монтажа. Они разработаны, чтобы быть временными объектами — они только связаны с единственной областью монтажа, и только с одним количеством изменения, таким образом, Вы не должны поддерживать их после того, как Вы создали их и поместили их на область монтажа.

Запись

Следующий пример иллюстрирует, как Вы могли бы использовать NSPasteboardItem объект создать элемент области монтажа с тремя представлениями — строка, приписал строку и табличный текст. Данные для этих представлений обещаны провайдером данных — в этом случае, self. Провайдер данных должен соответствовать NSPasteboardItemDataProvider Protocol протокол. В его реализации pasteboard:item:provideDataForType:, это генерирует и возвращает запрошенные данные.

NSPasteboardItem *pasteboardItem = [[NSPasteboardItem alloc] init];
NSArray *types = [[NSArray alloc] initWithObjects:
    [NSPasteboardTypeRTF, NSPasteboardTypeString, NSPasteboardTypeTabularText, nil];
BOOL ok = [pasteboardItem setDataProvider:self forTypes:types];
 
if (ok) {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    ok = [pasteboard writeObjects:[NSArray arrayWithObject:pasteboardItem]];
}
if (ok) {
    // Maintain the information required to provide the data if requested.
}

Чтение

Предположим, что на области монтажа существует пять элементов, два содержат данные TIFF, два содержат данные RTF, каждый содержит частный тип данных. Вызов readObjectsForClasses:options: только с NSImage класс возвратит массив, содержащий два объекта изображения. Вызов только с NSAttributedString класс возвратит массив, содержащий две приписанных строки. Вызов с обоими классами (NSImage и NSAttributedString) возвратит два объекта изображения и две приписанных строки.

Заметьте, что в предыдущих примерах, количество объектов возвратилось, меньше, чем число элементов на области монтажа. Только объекты требуемых классов возвращаются. Если Вы добавляете NSPasteboardItem класс массива, тогда Вы будете всегда возвращать массив, содержащий то же число объектов, поскольку существуют элементы на области монтажа. Так как Вы обеспечиваете элементы в массиве классов в Вашем предпочтительном порядке, необходимо добавить NSPasteboardItem класс до конца массива.

// NSPasteboard *pasteboard = <#Get a pasteboard#>; 
NSArray *classes = [[NSArray alloc] initWithObjects:
                    [NSImage class], [NSAttributedString class], [NSPasteboardItem class], nil];
NSDictionary *options = [NSDictionary dictionary];
NSArray *copiedItems = [pasteboard readObjectsForClasses:classes options:options];
if (copiedItems != nil) {
    // Do something with the contents.

В этом случае метод возвратит массив с двумя изображениями, двумя приписанными строками и одним элементом области монтажа, содержащим частный тип данных.