从 NSAttributedString 中的 nsfilewrapper / nstextattachment 获取文件名和路径

发布于 2025-01-01 23:14:33 字数 464 浏览 1 评论 0原文

我有一个基本的 NSTextView,启用了富文本和图形(在 IB 中)。我想要获取的是拖入的任何图像的路径和文件名,以便我可以将它们传递给另一个类。

我是 NSAttributedString 的新手,但我有一个使用 enumerateAttributesInRange:options:usingBlock: 寻找 NSattachmentAttributeName 的循环,一切正常。但更深入地说,我到达 fileWrapper 类,它显然无法为我提供项目的路径。

我将如何获取 NSTextAttachment 的名称和路径?

相关:是否有更简单的方法来获取所有这些属性,然后逐步遍历属性?

非常感谢!

I have a basic NSTextView with rich text and graphics enabled (in IB). What I'd like to get is the path and filename of any images dragged in so I can pass those to another class.

I'm new to NSAttributedString but I've got a loop using enumerateAttributesInRange:options:usingBlock: looking for NSAttachmentAttributeName and that's all working fine. But going deeper, I get to the fileWrapper class and it's apparent inability to give me the path of the item.

How would I go about getting the name and path of the NSTextAttachment?

Related: Is there an easier way to get them all then stepping through the attributes?

Thanks much!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

下壹個目標 2025-01-08 23:14:33

虽然我个人鄙视 NSFileWrapper 的设计,但如果您只需要每个附件的数据,您可以通过 NSFileWrapper 的 regularFileContents 方法将其作为 NSData 实例访问。但是,我的应用程序需要一个有效且明确的附件路径名。要获得它比应有的工作要多得多:

您可以子类化您的 NSTextView 并重写 NSDraggingDestination 协议方法 draggingEntered: 并且您可以在拖动操作期间遍历传递到应用程序的 NSPasteboardItem 对象。我选择将路径名及其索引节点号保留在 NSMutableDictionary 中,因为 NSFileWrapper 可以为您提供引用文件的索引节点。稍后,当我通过 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];
}

我的解决方案的一个问题不会影响我的应用程序,那就是拖到视图中的多个文件(单独或一起)是同一文件的硬链接,只会被索引为添加到字典中的最后一个路径名,共享索引节点。根据您的应用程序如何使用路径名,这可能是一个问题。

While I personally hold the design of NSFileWrapper in contempt, if you just need the data of each attachment you can access it as an NSData instance via NSFileWrapper's regularFileContents method. However, I needed a valid and explicit pathname to the attachment for my application. To get it is much more work than it should be:

You can subclass your NSTextView and override the NSDraggingDestination Protocol method draggingEntered: and you can traverse the NSPasteboardItem objects passed to your application during the dragging operation. I chose to keep the pathname and its inode number in an NSMutableDictionary, as NSFileWrapper can provide you with the inode of the referenced file. Later, when I access the NSTextView contents via an NSAttributedString, I can fetch the pathname of an attachment using the inode as an index.

- (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];
}

One issue with my solution, that doesn't effect my application, is that multiple files dragged into the view (either singly or together) which are hard links to the same file, will only be indexed as the last pathname added to the dictionary which shares the inode. Depending on how the pathnames are utilized by your application this could be an issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文