Получение имени файла и пути из nsfilewrapper / nstextattachment в NSAttributedString - PullRequest
5 голосов
/ 04 февраля 2012

У меня есть базовый NSTextView с включенным форматированным текстом и графикой (в IB). То, что я хотел бы получить, это путь и имя файла любых изображений, которые перетаскиваются, чтобы я мог передать их другому классу.

Я новичок в NSAttributedString, но у меня есть цикл, использующий enumerateAttributesInRange:options:usingBlock: в поисках NSAttachmentAttributeName, и все работает нормально. Но, углубляясь, я попадаю в класс fileWrapper, и он не может дать мне путь к элементу .

Как мне узнать имя и путь к NSTextAttachment?

Связанный: есть ли более простой способ получить их все, чем пройтись по атрибутам?

Большое спасибо!

1 Ответ

8 голосов
/ 16 февраля 2012

Хотя я лично отношусь к дизайну NSFileWrapper с презрением, если вам просто нужны данные каждого вложения, вы можете получить к ним доступ как к экземпляру NSData с помощью метода regularFileContents NSFileWrapper.Тем не менее, мне нужно было правильный и явный путь к приложению для моего приложения.Чтобы получить его, нужно выполнить гораздо больше работы, чем должно быть:

Вы можете создать подкласс NSTextView и переопределить метод протокола NSDraggingDestination draggingEntered:, а также обойти объекты NSPasteboardItem, переданные в приложение во время операции перетаскивания.Я решил сохранить путь и его номер inode в NSMutableDictionary, так как NSFileWrapper может предоставить вам inode указанного файла.Позже, когда я получаю доступ к содержимому NSTextView через NSAttributedString, я могу извлечь путь к вложению, используя индекс в качестве индекса.

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

Одна проблема с моим решением, которая не влияет на мое приложение,заключается в том, что несколько файлов, перетаскиваемых в представление (по одному или вместе), которые являются жесткими ссылками на один и тот же файл, будут проиндексированы только как последний путь, добавленный в словарь, который разделяет индекс.В зависимости от того, как имена путей используются вашим приложением, это может быть проблемой.

...