Подтвердить что ты не робот

Использование расширений для редактирования изображений в Yosemite в собственном приложении

В моем приложении OS X я хочу, чтобы пользователь мог редактировать изображения с соответствующими расширениями действий, установленными на его/ее Mac, например расширение разметки изображения, которое присутствует в Mail.app или TextEdit (для файлов RTFD с изображениями) - или инструмент восстановления Pixelmator, если он доступен. Насколько я помню, Apple объявляет на WWDC '14, для этого будет публичный API.

К сожалению, я не могу найти отправной пункт о том, как использовать расширения с точки зрения хост-приложения, ни документации, ни образцового кода.

Я выяснил, что вам нужно установить недокументированное свойство стиля NSSharingPicker на ненулевое значение, подобное этому:

- (IBAction)testSharingPicker:(id)sender
{
    NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:@[[self.listing.images.firstObject thumbImage]]];

    [picker setValue:@(1) forKey:@"style"];
    [picker setDelegate:self];

    [picker showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge];
}

Как только значение стиля установлено, вы знаете, что находитесь на правильном пути, потому что - (NSArray *)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker sharingServicesForItems:(NSArray *)items proposedSharingServices:(NSArray *)proposedServices вызывается с расширениями для редактирования изображений, установленными в моей системе, вместо обычных расширений общего доступа.

Вам также необходимо реализовать недокументированный метод делегата:

- (BOOL)sharingServicePicker:(NSSharingServicePicker *)sharingService shouldShowForView:(NSView*) inView
{
    return YES;
}

Но все же сборщик не появляется. Все, что я получаю, - это какая-то странная граница вокруг кнопки sender.

4b9b3361

Ответ 1

К сожалению, похоже, что Apple действительно предоставляет Action Extensions через NSTextView в настоящее время.

В ОС X NSTextView играет центральную роль в представлении расширений для пользователей.

Это достигается путем создания NSTextView и вставки изображения в него как NSFileWrapper, например (этот код адаптирован из TextEdit):

NSMutableAttributedString *attachments = [[NSMutableAttributedString alloc] init];
NSError *error;
    NSFileWrapper *wrapper = [[NSFileWrapper alloc] initWithURL:[NSURL fileURLWithPath:@"/Users/user/Downloads/Test.png"] options:NSFileWrapperReadingImmediate error:&error];
    if (wrapper) {
        NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:wrapper];
        [attachments appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
}

if ([attachments length] > 0) {
    NSRange selectionRange = [self.textView selectedRange];
    if ([self.textView shouldChangeTextInRange:selectionRange replacementString:[attachments string]]) {
        [[self.textView textStorage] replaceCharactersInRange:selectionRange withAttributedString:attachments];
        [self.textView didChangeText];
    }
}

NSTextView displaying Extensions

(Обратите внимание, что вставка изображения как NSTextAttachmentCell вызывает странный сбой - rdar://20333977)

Эта странная граница, о которой вы упоминаете, кажется, является средством выбора общего доступа, которое отображается при наведении на изображение в NSTextView, но слегка затененной кнопкой.

NSButton displaying private NSSharingServicePicker menu

Я наткнулся на ваше репо GitHub и внесли свой вклад в то, что я узнал об этом в этот запрос на растяжение.

Я сделал хакерское обходное решение, представив NSSharingServicePicker, как описано в вашем вопросе, а затем удерживая его на NSSharingService, возвращенном в sharingServicePicker:sharingServicesForItems:proposedSharingServices:. Затем сами службы могут быть вызваны с помощью performWithItems:, а данные возвращаются в sharingService:didShareItems:.

Мой код доступен здесь.

Ответ 2

На самом деле, хакерство "стиль" и реализация NSSharingServicePickerDelegate не нужны, следующий код более подходит (конечно, вы должны реализовать протокол NSSharingServiceDelegate):

- (IBAction)onServiceBtnClick:(id)sender {
NSURL *url = [self.quickLookItems firstObject];
NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];
if (image) {
    self.serviceBtn.hidden = YES;

    NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Sharing"];

    NSSharingService *service = [NSSharingService sharingServiceNamed:@"com.apple.Preview.Markup"];
    service.delegate = self;
    self.markupService = service;
    NSArray *services = @[ service ];

    for (NSSharingService *service in services) {
        NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:service.title action:@selector(share:) keyEquivalent:@""];
        [menu addItem:menuItem];
    }

    [menu popUpMenuPositioningItem:nil atLocation:[NSEvent mouseLocation] inView:nil];


    }
}

- (void)share:(NSMenuItem *)sender{
     NSURL *imageURL = [self.quickLookItems firstObject];
     [self.markupService performWithItems:@[imageURL]];
 }