🕊️

ExpoでInstagramに直接画像をシェアできるように実装しました🎉

2025/02/01に公開

はじめに

ExpoでInstagramにShare Extensionを挟まずに直接シェアする実装をしたので、記事にしました。Swiftなどの記事はあったのですが、Expoの記事やリポジトリは一個もなかったので、参考になると嬉しいです。

Share Extensionとは?

Share Extensionは、iOSやAndroid のアプリから別のアプリにコンテンツを共有するための仕組みです。
iOSだと、下記の画像のようなモーダルです。

こちらを使わずに、なるべくシームレスにボタンを押しただけでInstagramにシェアしていきたかったので、今回はShare Extensionを使用しません。

使ったライブラリとメソッド

使用したライブラリはReact Native Shareというライブラリです。
https://github.com/react-native-share/react-native-share

こちらのライブラリの中に、Share.openShare.shareSingleというメソッドがあります。

Share.open: Share Extensionを表示してInstagramに遷移をします。
Share.shareSingle: 直接Instagramに遷移をします。

今回は、Share.shareSingleを使用して、直接Instagramに遷移するよう実装します。

appIdを取得

shareOptionsの設定で、appIdを記述する必要があるので、Facebook DeveloperでappIdを作成してください。
https://developers.facebook.com/?locale=ja_JP

Facebook Developerにログインしたら、下記の画面になると思います。
アプリの作成を押下して、IDを取得できるようにします。

アプリ名を入力して

ユースケースを選びます。(私はわからなかったので広告にしました)

そのまま画面の通りに進んでいくと

ここに作ったアプリが表示されるので、記載されているIDをコピーしておきます!

実装

app.config.tsにinfo.plistに入れる値を設定します。
https://react-native-share.github.io/react-native-share/docs/install#expo-managed-workflow

apps/mobile/app.config.ts
const commonConfig: ExpoConfig = {
  name: 'mii',
  ・・・
  ios: {
    supportsTablet: true,
    buildNumber: '1',
    googleServicesFile: process.env.GOOGLE_SERVICES_INFO_PLIST,
    //ここを追加
    infoPlist: {
      LSApplicationQueriesSchemes: ['instagram', 'instagram-stories'],
    },
  },
  ・・・
  plugins: [
  ・・・
  //ここにpluginの記述を追加
    [
      'react-native-share',
      {
        ios: ['fb', 'instagram', 'twitter', 'tiktoksharesdk'],
        android: ['com.facebook.katana', 'com.instagram.android', 'com.twitter.android', 'com.zhiliaoapp.musically'],
      },
    ],
    ・・・
  ],
  ・・・
}

上記のコードを書き終えたらプレビルドを行ってください。

次に、シェア機能を実装していきます。
画像URLをBase64にエンコードし、Instagramに送ります。先ほど取得したIDはここに入れます。

apps/mobile/src/app/home/index.tsx
export default function Tab() {
//Base64にエンコード
const convertImageToBase64 = async (url: string) => {
    try {
      const response = await FileSystem.downloadAsync(url, FileSystem.cacheDirectory + 'tempImage.jpg')
      const base64Image = await FileSystem.readAsStringAsync(response.uri, { encoding: FileSystem.EncodingType.Base64 })
      return `data:image/jpeg;base64,${base64Image}`
    } catch (error) {
      console.error('❌ Error converting image:', error)
      return null
    }
  }

  //IGに画像を投稿
  const postToIGImage = async () => {
    const base64Image = await convertImageToBase64('https://chiikawa-info.jp/images/pic06.jpg')

    if (!base64Image) {
      Alert.alert('エラー', '画像の変換に失敗しました。')
      return
    }

    const shareOptions = {
      social: Social.Instagram,
      url: base64Image,
      type: 'image/*',
      appId: '000000000000',//ここにFacebook Developerで作成したIDを入力
    }

    try {
      const result = await Share.shareSingle(shareOptions)
      console.log('✅ Share result:', result)
    } catch (error: unknown) {
      console.error('❌ Error in sharing:', error)
      Alert.alert('Error', 'ストーリーへのシェアに失敗しました。')
    }
  }

  return (
    <View style={styles.container}>
      <Text>【Stack】 ホーム</Text>
      <Link href="/">👉 【Stack】 新規登録</Link>
      <Button
        text="postToIGImage"
        onClick={() => {
          postToIGImage().catch(error => {
            console.error('Error occurred while sharing:', error)
          })
        }}
      />
    </View>
  )
}

できた画面

iOSの画面

ボタンを押下すると画像の画面に遷移します。
ここからストーリーシェアかフィードシェアを選ぶことができます。

iOSのストーリーシェア

iOSのフィードシェア

Androidの画面

ボタンを押下すると画像の画面に遷移します。
ここからストーリーシェアかフィードシェアを選ぶことができます。

Androidのストーリーシェア

Androidのフィードシェア

直接ストーリーに画像を載せる方法

ボタンを押したら直接Instagramのストーリーに投稿する機能の実装も挑戦しました。

const shareOptions = {
      social: Social.InstagramStories,//ここをInstagramStoriesに変更
      url: base64Image,
      type: 'image/*',
      appId: '00000000000',
    }

こちらは、まだ実装できていないのですが、現時点で遷移と背景色の設定までうまくいったので、後は画像を上に載せることができたらまた別途で記事を書こうと思います。
InstagramStoriesに記載を変えただけではうまくいかないようです😿

ここまでは実装できたのですが...🥺もう少し調査します❤️‍🔥

さいごに

今回は、ExpoのShare.shareSingleの実装について書きました。現時点でSNSアプリの中でTikTokとYoutubeのシェアはできないので、ご注意ください。

Discussion