2015-02-22 6 views
2

У меня есть объект, который принадлежит к этому классу, который содержит следующие объявления:Хранение и извлечение пользовательского объекта из NSPasteBoard

ЗАГОЛОВКА

@interface MyClassObject : NSObject <NSCopying, NSPasteboardWriting, NSPasteboardReading> 

@property (nonatomic, strong) NSArray *children; 
@property (nonatomic, assign) NSInteger type; 
@property (nonatomic, strong) NSString *name; 
@property (nonatomic, strong) id node; 

children держит другие объекты этого класса, node держит объекты, которые могут быть NSView или NSImageView.

Я хотел был бы иметь возможность копировать и вставлять объекты этого типа в/из NSPasteboard.

У меня есть google, но объяснения неясны.

Что мне делать, чтобы сделать этот класс доступным для чтения/удобочитаемым для NSPasteboard или другими словами, привести его в соответствие с протоколами NSPasteboardWriting и NSPasteboardReading?

У меня нет ни малейшего понятия о том, как это делается, и, как обычно, Apple documetation и ничего не то же самое.

+0

сравнения: http://stackoverflow.com/questions/7243668/nspasteboard-and-simple-custom-data?rq=1 –

ответ

6

Это co мапт.

Первое, что нужно сделать, чтобы класс соответствовал NSCoding. В этом случае объявление класса будет

@interface MyClassObject : NSObject <NSCopying, NSPasteboardWriting, NSPasteboardReading, NSCoding> 

Чтобы сделать его совместимым с NSCoding вы должны реализовать encodeWithCoder: и initWithCoder: ... в моем случае:

- (void)encodeWithCoder:(NSCoder *)coder { 

    [coder encodeObject:@(self.type) forKey:@"type"]; 
    [coder encodeObject:self.name forKey:@"name"]; 
    // converting the node to NSData... 
    // the object contained in node must be compatible with NSCoding 
    NSData *nodeData = [NSKeyedArchiver archivedDataWithRootObject:self.node]; 
    [coder encodeObject:nodeData forKey:@"node"]; 

    NSData *childrenData = [NSKeyedArchiver archivedDataWithRootObject:self.children]; 
    [coder encodeObject:childrenData forKey:@"children"]; 

} 

- (id)initWithCoder:(NSCoder *)coder { 

    self = [super init]; 

    if (self) { 

    _type = [[coder decodeObjectForKey:@"type"] integerValue]; 
    _name = [coder decodeObjectForKey:@"name"]; 

    NSData *nodeData = [coder decodeObjectForKey:@"node"]; 
    _efeito = [NSKeyedUnarchiver unarchiveObjectWithData:nodeData]; 

    NSData *childrenData = [coder decodeObjectForKey:@"children"]; 
    _children = [NSKeyedUnarchiver unarchiveObjectWithData:childrenData]; 
    _parent = nil; // I want this to be nil when the object is recreated 
    } 

Чтобы сделать работу класса с NSPasteboard вас необходимо добавить эти 4 метода:

-(id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type { 
    return [NSKeyedUnarchiver unarchiveObjectWithData:propertyList]; 
} 


+(NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard { 
    // I am using the bundleID as a type 
    return @[[[NSBundle mainBundle] bundleIdentifier]]; 
} 

- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard { 
    // I am using the bundleID as a type 
    return @[[[NSBundle mainBundle] bundleIdentifier]]; 
} 


- (id)pasteboardPropertyListForType:(NSString *)type { 
    // I am using the bundleID as a type 
    if(![type isEqualToString:[[NSBundle mainBundle] bundleIdentifier]]) { 
    return nil; 
    } 

    return [NSKeyedArchiver archivedDataWithRootObject:self]; 
} 

Затем на классе вы реализуете скопировать и вставить добавления:

- (void)copy:(id)sender { 

    NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; 
    [pasteBoard clearContents]; 

    NSArray *copiedObjects = @[theObjectYouWantToCopyToThePasteboard]; 
    [pasteBoard writeObjects:copiedObjects]; 

} 

- (void)paste:sender { 

    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 
    NSArray *classArray = @[[LayerObject class]]; 
    NSDictionary *options = [NSDictionary dictionary]; 

    BOOL ok = [pasteboard canReadItemWithDataConformingToTypes:@[[[NSBundle mainBundle] bundleIdentifier]]]; 

    if (ok) { 
    NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options]; 
    MyObjectClass *object = [objectsToPaste objectAtIndex:0]; 

    // object is the one you have copied to the pasteboard 
    // now you can do whatever you want with it. 
    // add the code here.  
    } 
} 
+1

Это очень помогло мне. –

0

Илл только обсуждать письмо. это в основном то же самое для чтения (но в обратном направлении, конечно;))

записи

  1. объявить тип вы пишете

    - (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard { 
        return @[@"com.mycompany.mytype"]; 
    } 
    
  2. записать данные

    - (id)pasteboardPropertyListForType:(NSString *)type { 
        //check the type we are asked to write 
        if(![type isEqualToString:@"com.mycompany.mytype"]) return nil;  
    
        //create a _plist_ object 
        // :: ONLY PLIST TYPES 
        NSMutableDictionary *plist = [[NSMutableDictionary alloc] init]; 
    
        ... 
    
        return plist; 
    } 
    
+1

создать объект Plist? никогда не делал этого ... это слишком много для вас, чтобы включить код для этого? – SpaceDog

+0

может идти только то, что может пойти в userDefaults, что означает, что все должно кодироваться ... вы можете использовать NSCoder. –

+0

достаточно легко, за исключением детей и родителей –