gpt4 book ai didi

objective-c - 将 FileURL 的名称写入粘贴板

转载 作者:行者123 更新时间:2023-12-03 16:28:26 28 4
gpt4 key购买 nike

我想使用 [pasteboard writeObjects:pasteboardArray]; 将一些 fileURL 写入通用粘贴板,其中 pasteboard 是通用粘贴板和 pasteboardArray 的对象> 是 NSURL 的 NSArray。它在粘贴板上写下 url,例如

文件://localhost/Usr/

文件://localhost/Vol/

...等等

我想将这些 URL 写成如下

用户

音量

..等等

即仅文件/目录的名称,就像系统在复制任何文件/目录时所做的那样。

最佳答案

对于粘贴板上的每个项目,可以有多种类型的数据。当您将 NSURL 写入粘贴板时,它会放置诸如 public.file-url (UTF-8 文本形式的 URL)、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:)。或者它可能使用其 -set...:forType: 方法构造具有所需类型和数据的 NSPasteboardItem 实例,然后将这些项目写入粘贴板。

根据您的需要,执行以下操作可能就足够了:

[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 复制文件时应用程序得到的结果略有不同,其中字符串与回车符连接。某些应用程序可能无法很好地应对这种差异。

关于objective-c - 将 FileURL 的名称写入粘贴板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28504213/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com