2015-02-02 3 views
13

Nella mia app OS X, voglio consentire all'utente di modificare le immagini con le estensioni di azione appropriate installate sul suo Mac, ad esempio l'estensione di markup dell'immagine presente in Mail.app o TextEdit (per i file RTFD con immagini) - o lo strumento di riparazione di Pixelmator, se disponibile. Per quanto posso ricordare, Apple annuncia al WWDC '14 che ci sarebbe un'API pubblica per questo compito.Uso delle estensioni di modifica delle immagini su Yosemite nella propria app

Purtroppo non riesco a trovare alcun punto di partenza su come utilizzare le estensioni dal punto di vista dell'app host, né sulla documentazione, né sul codice di esempio.

ho scoperto che è necessario impostare la proprietà di stile non documentata del NSSharingPicker ad un valore diverso da zero in questo modo:

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

Una volta che il valore dello stile è impostato, sai che sono sulla strada giusta , perché il - (NSArray *)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker sharingServicesForItems:(NSArray *)items proposedSharingServices:(NSArray *)proposedServices viene chiamato con le estensioni per la modifica delle immagini installate sul mio sistema, invece delle normali estensioni di condivisione.

È inoltre necessario implementare un metodo delegato non documentato:

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

Ma ancora, il selettore non viene visualizzata. Tutto ciò che ottengo è un bordo strano attorno al pulsante sender.

+0

hai giocato con '-sharingService: sourceFrameOnScreenForShareItem: '' - sharingService: transitionImageForShareItem: contentRect: 'e' -sharingService: sourceWindowForShareItems: sharingContentScope: '? – catlan

+0

Sì, ho implementato tutti questi metodi. Non fa alcuna differenza Non arrivo al punto in cui sono chiamati. – iljawascoding

+0

eMail <[email protected]> o presentare una richiesta di miglioramento (bug report @: ) e richiedere una risposta ufficiale. – geowar

risposta

3

Sfortunatamente, sembra che Apple esponga attualmente solo le estensioni di azione tramite NSTextView.

On OS X, NSTextView plays the central role in presenting Extensions to the users.

Ciò è realizzabile creando un NSTextView ed inserendo un'immagine in esso come NSFileWrapper, per esempio (questo codice adattato da 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

(Si noti che l'inserimento di un'immagine come NSTextAttachmentCell causa uno strano incidente - rdar://20333977

Quel bordo strano che hai menzionato sembra essere il Selettore di servizio di condivisione che viene mostrato quando si passa sopra un'immagine in un NSTextView, tuttavia leggermente oscurato dal pulsante.

NSButton displaying private NSSharingServicePicker menu

mi sono imbattuto su your GitHub repo e hanno contribuito quello che ho imparato su di esso in this pull request.

Ho raggiunto una soluzione hacky presentando lo NSSharingServicePicker come descritto nella domanda e quindi trattenendo lo NSSharingService s restituito in sharingServicePicker:sharingServicesForItems:proposedSharingServices:. I servizi stessi possono quindi essere richiamati con performWithItems: e i dati vengono restituiti in sharingService:didShareItems:.

Il mio codice è disponibile here.

0

In realtà, l'hacking proprietà "stile" e l'attuazione di NSSharingServicePickerDelegate sono inutili, il seguente codice è più ammissibile (naturalmente, è necessario implementare il protocollo 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]]; 
}