Hahnah Chronicle

[Swift] UIActivityViewController を使って Facebook/Twitter でシェアしたりカメラロールに保存したりする方法

Authors
原井 夏樹
Published on
Updated on

iOSでよくある Activity のシェア機能を実装する方法を紹介する。UIActivityViewControllerを使うと簡単に実装できる。

ios-activity-button

↑ のボタンを押すと Facebook 投稿や画像保存など、 Activity の候補が出てきて、その中から選んで実行できるという、

よくあるこの機能を実装する方法を紹介する。

uiactivity-description-image

実装

activityButtonをツールバー上に設置し、これがタップされるとshowActivityView(_ sender: メソッドを呼び出して UIActivityView に画面遷移するように実装した。

(GitHubにもソースあり)

ViewController.swift

import UIKit
class ViewController: UIViewController {
var printingImage: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
// image
self.printingImage = UIImage(named: "sampleImage.png")
let imageView: UIImageView = UIImageView(image: self.printingImage)
let imageAspect: CGFloat = (self.printingImage?.size.height)! / (self.printingImage?.size.width)!
imageView.frame = CGRect(x: self.view.bounds.width * 0.05, y: self.view.bounds.height * 0.1, width: self.view.bounds.width * 0.9, height: self.view.bounds.width * 0.9 * imageAspect)
self.view.addSubview(imageView)
// toolbar
self.view.isOpaque = false
let toolbarHeight: CGFloat = 80
let toolbarPaddingBottom: CGFloat = 20
let toolbarRect: CGRect = CGRect(x: 0, y: self.view.bounds.height - toolbarHeight - toolbarPaddingBottom, width: self.view.bounds.width, height: toolbarHeight)
let toolbar: UIToolbar = UIToolbar(frame: toolbarRect)
let activityButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(self.showActivityView(_:)))
let buttonGap: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
toolbar.items = [buttonGap, activityButton, buttonGap]
self.view.addSubview(toolbar)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func showActivityView(_ sender: UIBarButtonItem) -> Void {
let activityItems: Array<Any> = [self.printingImage!]
let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
let excludedActivityTypes: Array<UIActivityType> = [
// UIActivityType.addToReadingList,
// UIActivityType.airDrop,
// UIActivityType.assignToContact,
// UIActivityType.copyToPasteboard,
// UIActivityType.mail,
// UIActivityType.message,
// UIActivityType.openInIBooks,
// UIActivityType.postToFacebook,
UIActivityType.postToFlickr,
UIActivityType.postToTencentWeibo
// UIActivityType.postToTwitter,
// UIActivityType.postToVimeo,
// UIActivityType.postToWeibo,
// UIActivityType.print,
// UIActivityType.saveToCameraRoll,
// UIActivityType.markupAsPDF
]
activityViewController.excludedActivityTypes = excludedActivityTypes
activityViewController.completionWithItemsHandler = { (activityType: UIActivityType?, completed: Bool, returnedItems: [Any]?, activityError: Error?) in
guard completed else { return }
switch activityType {
case UIActivityType.postToTwitter:
print("Tweeted")
case UIActivityType.print:
print("Printed")
case UIActivityType.saveToCameraRoll:
print("Saved to Camera Roll")
default:
print("Done")
}
}
self.present(activityViewController, animated: true, completion: nil)
}
}

UIActivityViewControllerを扱う際に抑えたいポイントは主に3つだ。

ポイント1

activityItemsに、投稿/保存などしたいものを指定してイニシャライズすること。
UIActivityViewController(activityItems:applicationActivities:)

ちなみに、異なるクラスのインスタンスが混ざっていてもよく、例えば次のようなものをよく使うことになるだろう。

  • UIImage (画像)
  • URL (URL)
  • String (テキスト)

念の為補足すると、画像をアルバムに保存するような Activity がなされる場合には
Privacy - Photo Library Additions Usage Description
を info.plist に記述することが必要。

ポイント2

excludedActivityTypesプロパティで、除外したい AcivityType を指定すること。

例えば Flickr と Tencent Weibo ではシェアしないという想定なのであれば、次のように書く。

activityViewController.excludedActivityTypes = [
UIActivityType.postToFlickr,
UIActivityType.postToTencentWeibo
]

除外するものを指定するわけなので、この設定は必須でない
設定しなければ、単にすべてが選択肢になるというだけである。

ActivityType 一覧の最新情報は Apple のドキュメントで確認できる。

ActivityType概要
addToReadingListSafari のリーディングリストへ追加する
airDropAir Drop で近くの端末にシェアする
assignToContact連絡先 に ActivityItems を渡す
copyToPasteboardペーストボード(クリップボード)へコピーする
mailメール でシェアする
messageメッセージ でシェアする
openInIBooksiBooks にPDFとして保存する
postToFacebookFacebook でシェアする
postToFlickrFlickr でシェアする
postToTencentWeiboTencent Weibo でシェアする
postToTwitterTwitter でシェアする
postToVimeoViemo でシェアする
postToWeiboWeibo でシェアする
print印刷する
saveToCameraRollカメラロールに保存する
markupAsPDFPDFを作成する

ちなみに、Activity で呼び出される各アプリは、端末にインストールされていなければ実行時に選択肢として表示されない

ポイント3

completionWithItemsHandlerプロパティに完了時の処理を記述する これも任意だ。

サンプルコードではactivityTypeに応じて処理を変えている。

switch activityType {
case UIActivityType.postToTwitter:
print("Tweeted")
case UIActivityType.print:
print("Printed")
case UIActivityType.saveToCameraRoll:
print("Saved to Camera Roll")
default:
print("Done")
}

参考