Developer's Blog

NSSharingService を使ってかっこいい共有を実装する

nssharingservice-on-sleipnir

こんにちは。Mac/iOS アプリケーションエンジニアの福井です。

Mountain Lion から OS X でもNSSharingServiceの導入により外部サービスとの連携が簡単にできるようになりました。NSSharingServiceは iOS の Social.framework とはひとあじ違い、OS X ならではのリッチなトランジションも実装することができます。今日はそんな NSSharingService の使い方をご紹介します。

NSSharingServiceとは?

Sleipnir から Web サービス連携が使える Fenrir Pass Connect は便利ですが、中には Mountain Lion から追加された OS X の設定を使いたい人もいるでしょう。Mountain Lion から OS X に統合された共有機能を使うには、NSSharingServiceを使います。OS X に統合された共有機能とはどんなものでしょうか?まずは Safari の共有ボタンの動作を見てみましょう。

共有ボタンを押す

共有ボタンを押すとこんなメニューが出てきます。

Twitterに投稿してみる

Twitter を選択しました。ウインドウにはサムネイルが挿入されたり、ウインドウを表示するトランジションがあったりとかなりかっこいいです。

NSSharingService使ってみた

Safari の共有ボタンのように共有先を選ぶ動作をさせるには直接NSSharingServiceを使うのではなく、NSSharingServicePickerを使います。以下のコードをボタンのクリックイベントに仕込みます。

- (IBAction)shareClicked:(id)sender
{
    NSArray *items = [NSArray arrayWithObjects:title, URL, nil];
    NSSharingServicePicker *picker = [[[NSSharingServicePicker alloc] initWithItems:items] autorelease];
    [picker showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge];
}

上記のように、表示している Web ページのタイトルと、URL を item として設定して表示してみると、メニューが表示されました。さきほどと同じように共有先に Twitter を選んでみましょう。

NSSharingService使ってみた

あれ?Safari の共有と少し違います。サムネイルは無く、URL は普通に文字列として挿入されています。共有ウインドウの表示までのトランジションや動作も微妙に Safari のものと違ってショボい感じがします。これで終わりではあまりに残念すぎます。満を持して統合された連携機能がこんな中途半端なもので終わるはずがありません。Safari と同じように実装できるのではないでしょうか。

NSSharingServiceDelegateを使ってトランジションを実装する

リッチなトランジションの秘密はNSSharingServiceDelegateにありました。NSSharingServiceDelegateCustomizing TransitionAnimation という項目があります。以下の3つのメソッドです。それぞれ役割を見てみましょう。

– (NSRect)sharingService:(NSSharingService *)sharingService sourceFrameOnScreenForShareItem:(id <NSPasteboardWriting>)item

共有ウインドウにクリップされる画像が表示されている場合、画面上の rect を返します。設定すると画面上に表示されているコンテンツが共有ウインドウに移動するトランジションが自動で追加されます。

– (NSImage *)sharingService:(NSSharingService *)sharingService transitionImageForShareItem:(id <NSPasteboardWriting>)item contentRect:(NSRect *)contentRect

共有ウインドウにクリップされるイメージを返します。Sleipnir for Macの場合は Web ページのサムネイルを返します。もちろんNSImageViewなどで表示しているものを返すことも可能です。

– (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope

共有ウインドウを表示したウインドウを返します。ここで返したウインドウは共有ウインドウを表示している間、dim がかかり操作をブロックすることができます。非常に地味ですが、あるとないでは大違いです。細かいところまで気がきいていますね。

再度動かしてみる

NSSharingServicePickerを使った場合は直接NSSharingServiceを生成しないので、実際に使われるオブジェクトにNSSharingServiceDelegateを指定することができません。NSSharingServicePickerDelegateを使ってデリゲートオブジェクトを指定します。

- (IBAction)shareClicked:(id)sender
{
    NSArray *items = @[title, URL];
    NSSharingServicePicker *picker = [[[NSSharingServicePicker alloc] initWithItems:items] autorelease];
    picker.delegate = self;
    [picker showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge];
}

#pragma mark - NSSharingServicePickerDelegate

- (id <NSSharingServiceDelegate>)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker delegateForSharingService:(NSSharingService *)sharingService
{
    // NSSharingServiceDelegate を実装したオブジェクトを返す
    return self;
}

#pragma mark - NSSharingServiceDelegate

- (NSRect)sharingService:(NSSharingService *)sharingService sourceFrameOnScreenForShareItem:(id<NSPasteboardWriting>)item
{
    // クリップされる画像のスクリーン上での座標
    return [self.view.window convertRectToScreen:self.frame];
}

- (NSImage *)sharingService:(NSSharingService *)sharingService transitionImageForShareItem:(id<NSPasteboardWriting>)item contentRect:(NSRect *)contentRect
{
    // クリップされる画像
    return self.presentingImage;
}
- (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope
{
    // 呼び出し元ウインドウ
    return self.view.window;
}

これでもう一度動かしてみると…

NSSharingDelegateを実装する

Safari の共有ボタンのような挙動になりました!文字列として挿入されていた URL も画像になり、リッチ感が増しましたね。画像からはわかりませんが、共有ウインドウが出現する際のトランジションもよりリッチになっています。次回リリースの Sleipnir for Mac では OS X の共有機能を使えるようになりますので、実際に触ってみて動作の確認をしてみてください。

まとめ

  • NSSharingService を使うと簡単にシェア機能を実装することができる
  • システムのシェア機能を使う際のリッチなトランジションの秘密はNSSharingServiceDelegateにアリ!

今回紹介した、NSSharingServiceを使ったトランジションも魅力的ですが、Fenrir Pass Connect を使った共有のトランジションはもっと魅力的です。

自由自在に Web サービスと連携できるSleipnir for Mac はこちら

参考

Copyright © 2019 Fenrir Inc. All rights reserved.