虽然我个人认为NSFileWrapper的设计很鄙视,但如果您只需要每个附件的数据,则可以通过NSFileWrapper的regularFileContents
方法将其作为NSData实例进行访问。但是,我需要一个有效的显式路径名来指向我的应用程序的附件。要获得它应该比应该更多的工作:
您可以继承您的NSTextView并覆盖NSDraggingDestination协议方法draggingEntered:
,您可以遍历在拖动操作期间传递给您的应用程序的NSPasteboardItem对象。我选择将路径名和它的inode号保存在NSMutableDictionary中,因为NSFileWrapper可以为您提供引用文件的inode。后来,当我通过NSAttributedString访问NSTextView内容时,我可以使用inode作为索引获取附件的路径名。我的解决方案,这并不影响我的应用程序
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
// get pasteboard from dragging operation
NSPasteboard *pasteboard = [sender draggingPasteboard];
NSArray *pasteboardItems = [pasteboard pasteboardItems];
for (NSPasteboardItem *pasteboardItem in pasteboardItems) {
// look for a file url type from the pasteboard item
NSString *draggedURLString = [pasteboardItem stringForType:@"public.file-url"];
if (draggedURLString != nil) {
NSURL *draggedURL = [NSURL URLWithString:draggedURLString];
NSString *draggedPath = [draggedURL path];
NSLog(@"pathname: %@", draggedPath);
// do something with the path
// get file attributes
NSDictionary *draggedAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:draggedPath error:nil];
if (draggedAttributes == nil)
continue;
// the NSFileWrapper allows access to the absolute file via NSFileSystemFileNumber
// put the path and the inode (returned as an NSNumber) into a NSMutableDictionary
NSNumber *draggedInode = [draggedAttributes objectForKey:NSFileSystemFileNumber];
[draggedFiles setObject:draggedPath forKey:draggedInode];
}
}
return [super draggingEntered:sender];
}
一个问题,就是多个文件拖入视图(单独或一起),这是硬链接到同一个文件,只会被索引的最后一个路径名添加到共享inode的字典中。根据您的应用程序使用路径名的方式,这可能是一个问题。
不幸的是,由NSFileWrapper返回的属性字典不提供完整的路径名。 NSFileWrapper的设计通过拒绝提供对原始引用对象的路径名的访问来制造近视和不幸的封装假设。 – ctpenrose 2012-02-15 22:57:20