我想使用[pasteboard writeObjects:pasteboardArray];
将一些fileURL写入常规粘贴板,其中pasteboard
是普通粘贴板的对象,pasteboardArray
是NSURL的NSArray。它将网址写在粘贴板上,如
文件://本地主机/ USR /
文件://本地主机/体积/
......等等
我想把这些网址写成以下
USR
卷
..等等
,即只有系统在复制任何文件/目录时所执行的文件/目录名称。
答案 0 :(得分:3)
对于粘贴板上的每个项目,可以有多种类型的数据。当您向粘贴板写入NSURL
时,它会将public.file-url
(URL为UTF-8文本),NSFilenamesPboardType
等类型(文件路径字符串数组)序列化为XML属性列表),“Apple URL粘贴板类型”(文件URL字符串数组,序列化为XML属性列表)和public.utf8-plain-text
(URL为UTF-8文本)。
当您在Finder中复制文件时,它会放置许多相同的类型,尽管它似乎首先将URL转换为文件引用URL。此外,它将文件的图标设置为ICNS和TIFF图像。但是,public.utf8-plain-text
类型只包含文件名,而不包含其URL。该字符串也存在类型public.utf16-plain-text
。
因此,据推测,Finder并不是简单地使用-writeObjects:
来填充粘贴板。它可能使用-declareTypes:owner:
和/或-addTypes:owner:
的旧方法,后跟-set...:forType:
(例如-setString:forType:
)。或者它可能正在使用NSPasteboardItem
方法构造具有所需类型和数据的-set...:forType:
实例,然后将这些项目写入粘贴板。
根据您的需要,可能就足够了:
[pasteboard writeObjects:arrayOfURLs];
NSMutableString* names = [NSMutableString string];
for (NSURL* url in arrayOfURLs)
{
NSString* name;
if ([url getResourceValue:&name forKey:NSURLLocalizedNameKey error:NULL])
{
if (names.length)
[names appendString:@"\r"];
[names appendString:name];
}
}
if (names.length)
{
[pasteboard addTypes:@[(__bridge NSString*)kUTTypeUTF8PlainText] owner:nil];
[pasteboard setString:names forType:(__bridge NSString*)kUTTypeUTF8PlainText];
}
注意:当您向粘贴板写入多个URL时,会有多个项目,每个项目都有多种类型。但是,某些类型用于整个集合,而这些仅用于第一个项目。普通字符串类型和NSFilenamesPboardType
是这样的。上面的代码将普通字符串放在第一个项目上,并包含由回车符分隔的所有URL的显示名称(这是Finder所做的)。
以上所述,目前尚不清楚您是否希望粘贴板包含只是 URL的显示名称,而不是任何表示中的URL本身。在这种情况下,只需从URL的显示名称创建一个字符串数组,并将该数组传递给-writeObjects:
即可。
更新
我找到了一种方法来更接近地匹配Finder所做的事情,同时采取一些捷径:
NSMutableArray* arrayOfPaths = [arrayOfURLs valueForKey:@"path"];
[pasteboard setPropertyList:arrayOfPaths forType:NSFilenamesPboardType];
NSMutableString* names = [NSMutableString string];
BOOL first = YES;
for (NSURL* url in arrayOfURLs)
{
NSString* name;
if (![url getResourceValue:&name forKey:NSURLLocalizedNameKey error:NULL])
name = @"";
if (first)
first = NO;
else
[names appendString:@"\r"];
[names appendString:name];
}
if (names.length)
{
[pasteboard addTypes:@[(__bridge NSString*)kUTTypeUTF8PlainText] owner:nil];
[pasteboard setString:names forType:(__bridge NSString*)kUTTypeUTF8PlainText];
}
当您为类型NSFilenamesPboardType
设置数据时,Cocoa会自动设置多个项目,每个项目对应于数组中的每个元素。第二个和后续的每个都只有单一类型public.file-url
。第一个项目具有该类型以及Finder放在粘贴板上的大多数其他项目,而不是图像类型。然后,只需在第一个项目上设置字符串值即可。
包含NSFilenamesPboardType
类型非常重要,因为在添加对多个粘贴板项目的支持之前,这就是粘贴板上显示多个文件的方式。有些应用可能仍然依赖于此。
另外,如果你单独提供每个项目的字符串数据(如你自己的答案中所做的那样),那么一个从粘贴板整体请求字符串的应用程序(即[pasteboard stringForType:NSStringPboardType]
)会将它们连接起来换行。这与从Finder复制文件时应用程序获得的内容略有不同,其中字符串与回车连接。有些应用可能无法很好地应对差异。
答案 1 :(得分:1)
NSMutableArray *archive=[NSMutableArray array];
for (int i = 0; i < [pasteboardArray count]; i++) {
NSPasteboardItem *item = [[NSPasteboardItem alloc] init];
NSURL *url = [pasteboardArray objectAtIndex:i];
if (url != nil) {
[item setString:[url lastPathComponent] forType:(__bridge NSString*)kUTTypeUTF8PlainText];
NSString *str = [NSString stringWithFormat:@"%@",url];
[item setData:[str dataUsingEncoding:NSUTF8StringEncoding] forType:(__bridge NSString*)kUTTypeFileURL];
}
[archive addObject:item];
}
[pasteboard writeObjects:archive];
这对我有用,其中pasteboard
是普通粘贴板的对象,而pasteboardArray
是NSURL的NSArray。欢迎任何更好的解决方案...