[React Native] 인스타그램 스토리에 이미지 공유하기

aborile·2023년 3월 15일
2

React Native

목록 보기
1/8
post-thumbnail

최종 수정일: 2023.03.20

이번에 진행하는 프로젝트에서 화면을 일부 캡처해서 그대로 인스타그램 스토리로 공유할 수 있게 해달라는 요청사항이 있었다.

현재 화면을 이미지로 캡처하기

react-native-view-shot 라이브러리를 사용하면 캡처하고자 하는 특정 영역을 ref로 걸어 쉽게 이미지로 캡처할 수 있다.

import { useRef } from "react";
import { Pressable, Text, View } from "react-native";
import ViewShot from "react-native-view-shot";

function ExampleViewShot() {
  // 캡처할 ViewShot 영역을 참조하는 ref
  const viewShotRef = useRef<ViewShot>();
  
  // onPress 액션을 통해 캡처를 실행
  const onPressCapture = async () => {
    const uri = await viewShotRef.current?.capture?.();
    // to do with uri
  };
  
  return (
    <View>
      <ViewShot ref={ref}>
        <View>
          <Text>Something to capture...</Text>
        </View>
      </ViewShot>

	  <Pressable onPress={onPressCapture}>
        <Text>Capture!</Text>
      <Pressable>
    </View>
  );
};

capture() 함수를 통해 해당 이미지의 uri를 string 형태로 제공받을 수 있다. 이때 주의할 점은, ViewShot 영역의 배경색을 명시적으로 지정하지 않으면 의도대로 동작하지 않을 수도 있다.

이외에도 ViewShot에 fileName, format, quality 등의 options를 전달해서 커스텀할 수 있다.

이미지를 인스타그램 스토리로 공유하기

이제 위에서 캡처한 이미지를 인스타그램 스토리로 공유하도록 연결하기만 하면 된다.

react-native-share 라이브러리에서 인스타그램 등의 다른 SNS로 공유하는 api를 쉽게 연동할 수 있는 기능을 제공해 준다. 특히, 인스타그램 스토리 연동은 이 docs에서 바로 확인할 수 있다.

import Share from "react-native-share";

Share.shareSingle({
  social: Share.Social.INSTAGRAM_STORIES, // 인스타그램 스토리로 공유
  appId: "facebook developer app id",
  backgroundImage: "배경으로 지정할 이미지의 URL",
  backgroundVideo: "배경으로 지정할 동영상의 URL",
  stickerImage: "sticker 형식으로(작게) 공유할 이미지의 URL", 
  backgroundBottomColor: "배경색 그라데이션의 bottom color, default #837DF4",
  backgroundTopColor: "배경색 그라데이션의 top color, default #906df4",
});

attributeUrl 옵션의 경우, 공식 문서 상으로는 facebook app 베타 기능이라고 적혀 있으나, 해당 라이브러리의 예전 이슈들과 인스타그램 공식 api 문서를 확인해 보면 현재는 deprecated된 기능이다.

위의 옵션에서 인스타그램 스토리임을 명시하는 socialappId 필드를 제외하고는 전부 optional한 기능이므로, 기획 사항에 따라 필요한 옵션만 골라서 사용하면 된다.

나의 경우, 단순히 이미지를 작게 공유하기만 하면 되었으므로 다음과 같이 함수를 구성하였다.

// ...생략

const onPressCaptureAndShare = async () => {
  const uri = await viewShotRef.current?.capture?.();
  if (uri) {
    const image = Platform.OS === "android" ? uri : `file://${uri}`;
    
    const { success } = await Share.shareSingle({
      social: Share.Social.INSTAGRAM_STORIES,
      appId: "APP-ID",
      stickerImage: image,
      backgroundBottomColor: BACKGROUND_COLOR, // 어플의 테마 컬러
      backgroundTopColor: BACKGROUND_COLOR,
    });
    
    // ...후략
  }
};

// ...후략

주의점 1. Android와 iOS의 viewShotRef.capture()에서 반환되는 uri 차이

위의 함수를 잘 봤다면 알겠지만 Android와 iOS에서 viewShotRef.capture()의 결과로 반환받는 uri 값에 차이가 존재한다. Android의 경우 file://FILE_NAME 꼴로 반환 받지만, iOS의 경우 바로 FILE_NAME 꼴로 나오기 때문에, share에서 정상동작을 위해 전처리를 해주었다.

주의점 2. iOS 인스타그램 공유 시 scheme 설정

iOS는 시뮬레이터를 사용한 개발만 해봤기 때문에 인스타그램 공유 기능을 개발 과정에서 실제로 해보지 못했는데, 나중에 실물 디바이스를 연결해서 살펴보니 정상동작하지 않았다. 인스타그램 스토리를 자동으로 만들어 주어야 하는데, 인스타그램을 실행하지 못하고 자꾸 앱스토어 인스타그램 페이지로 이동하는 것이었다.

iOS의 경우 외부 앱을 실행하기 위해서는 URL scheme을 설정해 주어야 하는데, 이 설정이 누락되었기 때문에 앱 실행에 실패한 것이다.

Info.plistLSApplicationQueriesSchemes 항목을 추가하여 인스타그램 스키마명을 배열에 넣어주면 해결된다.

	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>instagram</string>
		<string>instagramstories</string>
		<string>instagram-stories</string>
	</array>

주의점 3. Android 인스타그램 공유 시 Queries 설정

위의 iOS scheme 설정과 비슷하게, Android 11 이상에서는 다른 앱을 열기 위해서는 Queries를 설정해 주어야 한다. (나는 Android 10인 기종을 사용하여 개발하고 있었어서 개발하고 QA할 때까지만 해도 문제 없이 정상 동작하는 줄 알았다...)

이 내용이 react-native-share 공식 문서 - Installing 페이지 하단에 숨겨져 있는데... 해당 페이지 내에서는 필수가 아닌 것처럼 보이게 적혀 있고, 안드로이드 11에서만 문제가 된다고 되어 있으나, 안드로이드 공식 문서 상으로는 Android 11 이상이면 다 해당되는 것으로 적혀있고, 실제 동작도 그렇다.

Queris를 설정하지 않는 경우, shareSingle() 옵션을 사용해도 해당 어플리케이션이 열리는 것이 아니라, '연결 프로그램'이 뜨면서 갤러리 등 관련 없는 옵션이 보이게 된다.

다행히도 이를 설정하는 것이 어렵지는 않다. AndroidManifest.xml 내에 <queries>를 추가해 주면 된다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- insert this -->
  <queries>
    <package android:name="com.instagram.android" />
  </queries>
  
  <!-- other options ... -->
  <application ...>
  </application>
</manifest>

주의점? Share 내 options의 appId

필수 옵션으로 지정되어 있어서 facebook developer에 가입하며 app ID를 발급받았으나, 실제 ID가 아닌 아무 텍스트나 넘겨도 정상동작하는 것으로 보인다...

profile
기록하고 싶은 것을 기록하는 저장소

0개의 댓글