Instagramストーリーズに画像や動画を渡す

![iphonexspacegrey_portrait.png](https://qiita-image-store.s3.amazonaws.com/0/174081/a587ff46-6bf6-8456-dd23-19622051c36e.png)

## はじめに

Spotifyで聴いている音楽のジャケットをステッカーとして共有できたりなど、シェア項目にインスタグラムストーリーズを採用しているアプリが増えていますよね。僕自身も、いくつかの個人アプリに採用していますが、24時間で消滅するがゆえに、気軽にシェアしていただけるので、おススメです。

それらは、URLスキームとUIPasteboardの組み合わせで実装可能です。クリップボードにはこういった使い方もあるのですね、下記の公式ドキュメントを参考にSwift4で実装しています。

[ストーリーズへのシェア - Instagramプラットフォーム](https://developers.facebook.com/docs/instagram/sharing-to-stories/)

インスタグラムストーリーズに受け渡し可能なパラメータは以下の通りです。

- **必須項目**（どれか1つ以上）
    - バックグラウンド画像アセット
    - バックグラウンド動画アセット
    - スタンプアセット
- **オプション項目**
    - バックグラウンドレイヤーのトップカラー
    - バックグラウンドレイヤーのボトムカラー
    - アトリビューションURL (承認済みのアプリに限り投稿にURLがリンクされます)

## 実装コード

**Info.plistのLSApplicationQueriesSchemesキーにinstagram-storiesを追加**

```swift:InstaStories.swift
import UIKit

class InstaStories: NSObject {
    
    private let urlScheme = URL(string: "instagram-stories://share")!
    
    enum optionsKey: String {
        case stickerImage = "com.instagram.sharedSticker.stickerImage"
        case bgImage = "com.instagram.sharedSticker.backgroundImage"
        case bgVideo = "com.instagram.sharedSticker.backgroundVideo"
        case bgTopColor = "com.instagram.sharedSticker.backgroundTopColor"
        case bgBottomColor = "com.instagram.sharedSticker.backgroundBottomColor"
        case contentUrl = "com.instagram.sharedSticker.contentURL"
    }
    
    /// 背景画像を投稿
    func post(bgImage:UIImage, stickerImage:UIImage? = nil, contentURL:String? = nil) -> Bool{
        var items:[[String : Any]] = [[:]]
        //Background Image
        let bgData = bgImage.pngData()!
        items[0].updateValue(bgData, forKey: optionsKey.bgImage.rawValue)
        //Sticker Image
        if stickerImage != nil {
            let stickerData = stickerImage!.pngData()!
            items[0].updateValue(stickerData, forKey: optionsKey.stickerImage.rawValue)
        }
        //Content URL
        if contentURL != nil {
            items[0].updateValue(contentURL as Any, forKey: optionsKey.contentUrl.rawValue)
        }
        let isPosted = post(items)
        return isPosted
    }
    
    /// 背景動画を投稿
    func post(bgVideoUrl:URL, stickerImage:UIImage? = nil, contentURL:String? = nil) -> Bool{
        var items:[[String : Any]] = [[:]]
        //Background Video
        var videoData:Data?
        do {
            try videoData = Data(contentsOf: bgVideoUrl)
        } catch {
            print("Cannot open \(bgVideoUrl)")
            return false
        }
        items[0].updateValue(videoData as Any, forKey: optionsKey.bgVideo.rawValue)
        //Sticker Image
        if stickerImage != nil {
            let stickerData = stickerImage!.pngData()!
            items[0].updateValue(stickerData, forKey: optionsKey.stickerImage.rawValue)
        }
        //Content URL
        if contentURL != nil {
            items[0].updateValue(contentURL as Any, forKey: optionsKey.contentUrl.rawValue)
        }
        let isPosted = post(items)
        return isPosted
    }
    
    /// ステッカー画像を投稿
    func post(stickerImage:UIImage, bgTop:String = "#000000", bgBottom:String = "#000000", contentURL:String? = nil) -> Bool{
        var items:[[String : Any]] = [[:]]
        //Sticker Image
        let stickerData = stickerImage.pngData()!
        items[0].updateValue(stickerData, forKey: optionsKey.stickerImage.rawValue)
        //Background Color
        items[0].updateValue(bgTop, forKey: optionsKey.bgTopColor.rawValue)
        items[0].updateValue(bgBottom, forKey: optionsKey.bgBottomColor.rawValue)
        //Content URL
        if contentURL != nil {
            items[0].updateValue(contentURL as Any, forKey: optionsKey.contentUrl.rawValue)
        }
        let isPosted = post(items)
        return isPosted
    }
    
    /// Instagram Storiesへ投稿
    private func post(_ items:[[String : Any]]) -> Bool{
        guard UIApplication.shared.canOpenURL(urlScheme) else {
            print("Cannot open \(urlScheme)")
            return false
        }
        let options: [UIPasteboard.OptionsKey: Any] = [.expirationDate: Date().addingTimeInterval(60 * 5)]
        UIPasteboard.general.setItems(items, options: options)
        UIApplication.shared.open(urlScheme)
        return true
    }
    
}

// Singleton
extension InstaStories {
    class var Shared : InstaStories {
        struct Static { static let instance : InstaStories = InstaStories() }
        return Static.instance
    }
}
```

## 使用

以下のように呼び出せます(一例)

```swift:UIViewController.swift
// 背景画像をシェア
let isOpened = InstaStories.Shared.post(bgImage:img)
```

```swift:UIViewController.swift
// ステッカーをシェア　＋　背景色指定
let isOpened = InstaStories.Shared.post(stickerImage:img, bgTop:"#330000", bgBottom:"#000000")
```