在自己的应用中使用 Yosemite 上的图像编辑扩展
Using Image Editing extensions on Yosemite in own app
在我的 OS X 应用程序中,我想让用户使用 his/her Mac 上安装的适当操作扩展来编辑图像,例如图像标记扩展 [= =28=] 或 TextEdit(用于带图像的 RTFD 文件)- 或 Pixelmator 的修复工具(如果可用)。据我所知,Apple 在 WWDC '14 上宣布将有一个 public 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
按钮周围的一些奇怪的边框。
不幸的是,Apple 目前似乎只通过 NSTextView
公开 Action Extensions。
On OS X, NSTextView plays the central role in presenting Extensions to the users.
这可以通过创建 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];
}
}
(请注意,将图像作为 NSTextAttachmentCell
插入会导致奇怪的崩溃 – rdar://20333977)
您提到的那个奇怪的边框似乎是 NSTextView
中将鼠标悬停在图像上时显示的共享服务选择器,但是被按钮稍微遮住了。
我偶然发现了 your GitHub repo and have contributed what I've learnt about it in this pull request。
我通过按照您的问题中的描述提供 NSSharingServicePicker
,然后保留 sharingServicePicker:sharingServicesForItems:proposedSharingServices:
中返回的 NSSharingService
,实现了一个棘手的解决方法。然后可以使用 performWithItems:
调用服务本身,并在 sharingService:didShareItems:
.
中返回数据
我的代码可用 here。
其实,hacking "style" 属性和实现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]];
}
在我的 OS X 应用程序中,我想让用户使用 his/her Mac 上安装的适当操作扩展来编辑图像,例如图像标记扩展 [= =28=] 或 TextEdit(用于带图像的 RTFD 文件)- 或 Pixelmator 的修复工具(如果可用)。据我所知,Apple 在 WWDC '14 上宣布将有一个 public 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
按钮周围的一些奇怪的边框。
不幸的是,Apple 目前似乎只通过 NSTextView
公开 Action Extensions。
On OS X, NSTextView plays the central role in presenting Extensions to the users.
这可以通过创建 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];
}
}
(请注意,将图像作为 NSTextAttachmentCell
插入会导致奇怪的崩溃 – rdar://20333977)
您提到的那个奇怪的边框似乎是 NSTextView
中将鼠标悬停在图像上时显示的共享服务选择器,但是被按钮稍微遮住了。
我偶然发现了 your GitHub repo and have contributed what I've learnt about it in this pull request。
我通过按照您的问题中的描述提供 NSSharingServicePicker
,然后保留 sharingServicePicker:sharingServicesForItems:proposedSharingServices:
中返回的 NSSharingService
,实现了一个棘手的解决方法。然后可以使用 performWithItems:
调用服务本身,并在 sharingService:didShareItems:
.
我的代码可用 here。
其实,hacking "style" 属性和实现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]];
}