objective-c - NSSharingService 与 GIF 动画?

标签 objective-c cocoa

我是 Objective-C 的新手,但到目前为止我已经基本了解了所有内容。但是,我无法尝试通过 NSSharingService 共享动画 GIF。

我像这样附加图像,其中 image 是一个包含动画 GIF 的 URL 的字符串(例如 http://i.imgur.com/V8w9fKt.gif):

NSImage *imageData = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:image]];
NSArray *shareItems = [NSArray arrayWithObjects:imageData, href, nil];
NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeMessage];
service.delegate = self;
[service performWithItems:shareItems];

但是,当运行代码并发送消息时,图像将作为 PNG 文件而不是 GIF 文件发送。

我怀疑图像被 NSImageNSData 扁平化了,我需要先将图像保存到磁盘然后尝试发送它.不过,我想知道,如果没有额外的储蓄步骤,是否可以实现这一目标。

编辑 1:

我找到了一个 GitHub repo试图回答类似的问题。然而,从未找到解决方案,但最后一点建议是:

However, when I add an NSAttributedString with a GIF attachment to NSSharingServicePicker, the shared image is not animated. I can't add the wrapper RTFD data to the picker, as it can only share objects that support NSPasteboardWriting protocol, and the RTFD is returned as NSData.

Copying RTFD data to pasteboard as NSRTFDPboardType works and preserves animation

是否可以将 GIF 转换为 RTDF 对象,将其复制到粘贴板,检索粘贴板项目,然后共享该对象?还是无法使用 NSSharingService 保存动画?

编辑 2:

正如@Cocoadelica 在评论中提到的,我想知道是否需要 CoreImage 来保留动画。我尝试先将 GIF 文件保存到硬盘,然后将其加载到 NSImage,但它再次将其转换为静态 PNG。

这非常、非常、非常令人沮丧。

最佳答案

我最终通过 Cocoa-dev 邮件列表得到了回复。基本上,您需要附加一个直接链接到该文件的 NSURL。它不适用于外部图像,并且从未使用过 NSImage:

NSString *fileUrl = @"http://i.imgur.com/V8w9fKt.gif";
NSString *fileName = [fileUrl lastPathComponent];
NSURL *saveUrl = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", NSTemporaryDirectory()]];
saveUrl = [saveUrl URLByAppendingPathComponent:fileName];
// Write image to temporary directory
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileUrl]];
[data writeToURL:saveUrl atomically:YES];

// Attach the raw NSURL pointing to the local file
NSArray *shareItems = [NSArray arrayWithObjects:saveUrl, @"Text", nil];

// Open share prompt
NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeMessage];
service.delegate = self;
[service performWithItems:shareItems];

然后我实现了 didShareItems 和 didFailToShareItems 以便我可以在共享完成后删除文件:

- (void)sharingService:(NSSharingService *)sharingService didShareItems:(NSArray *)items{
    NSString *path = items[0];
    [self removeFile:path];
}

...

- (void)removeFile:(NSString *)path{
    [[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
}

对于那些苦苦挣扎的人,我发现需要以下方法才能正常工作:

- (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope{
    return self.window;
}

我意识到其中一些代码不正确(我的 URLWithString 创建是违反直觉的,但我正在学习),但这应该让那些苦苦挣扎的人有一个起点。

关于objective-c - NSSharingService 与 GIF 动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23598158/

相关文章:

iphone - 核心数据: fetch an NSManagedObject by its properties

objective-c - 如何填充内存以便稍后释放它?

ios - 当前 UIActivityViewController- LaunchServices :invalidationHandler called

macos - Mac系统上检测框架使用情况?

iphone - 在 Objective-c 中迭代类成员

objective-c - 使用非默认字体时,NSTextField 垂直错位文本

ios - Obj-C/iOS 是像 plist 这样的数据结构好还是像 coredata 这样的东西更容易使用?

objective-c - 为什么在设置 SHFileOperation ClientContext 的信息指针时收到 EXC_BAD_ACCESS?

iphone - 没有 @synthesis 的属性不会为自定义对象初始化

swift - 使用 Swift 和 Cocoa 处理 OS X 中的关键事件