이전 글에서 리액트 네이티브(React Native), Expo에서의 퍼미션에 대해서 공부했으니 이제는 직접 사진을 찍어볼 차례이다.

일단, 생각해보면 기본적으로 어디든 마찬가지겠지만 경로만 알면된다. 즉, 사진을 찍고 해당 사진의 경로를 반환해주면 된다.

일단 Expo에서의 카메라에 대한 지식이 전무하니 샘플 코드를 보았다.

가져온 샘플에서 추가할 것은 일단 Flip밖에 없으니 실제로 찍은 후, 내 화면으로 돌아오는 버튼을 만들어야 한다. 예제의 코드에서 버튼 두개만 아래처럼 추가한다.

<TouchableOpacity
  style={{
    flex: 0.33,
    alignSelf: 'flex-end',
    alignItems: 'center',
  }}
  onPress={
    // To do snap.
  }>
  <Text
    style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
    {' '}Snap{' '}
  </Text>
</TouchableOpacity>
<TouchableOpacity
  style={{
    flex: 0.33,
    alignSelf: 'flex-end',
    alignItems: 'center',
  }}
  onPress={
    // To do done.
    }>
  <Text
    style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
    {' '}Done{' '}
  </Text>
</TouchableOpacity>

이제 onPress쪽만 구현해주면 된다.

일단 Done을 눌렀을 때는 그냥 이전 Screen으로 돌아오는데, 경로를 함께 넘겨주면 된다. 즉 아래처럼 코딩한다.

onPress={() => {
  // alert(this.state.path);
  this.props.navigation.navigate('Create', { image: this.state.path })
}}

이제 가장 중요한 부분인 사진 찍는 부분인데… 이 부분은 여기를 참고했다.

snap = () => {
  if (this.camera) {
    this.camera.takePictureAsync({onPictureSaved: this.onPictureSaved});
  }
};

onPictureSaved = async photo => {
  let path = `${FileSystem.documentDirectory}photos/${Date.now()}.jpg`;
  await FileSystem.moveAsync({
    from: photo.uri,
    to: path,
  });
  this.setState({ path: path });
}

위와 같이 코딩하면 분명히 moveAsync에서 해당 path로 이동시키지 못했다는 에러가 난다. 그러므로 아래처럼 반드시 해당 디렉토리를 만들어 주도록 한다.

async componentDidMount() {
  try {
    await FileSystem.makeDirectoryAsync(
      `${FileSystem.documentDirectory}photos`,
      {
        intermediates: true,
      }
    )
  } catch (e) {
    console.log(e)
  }
}

그리고 가장 생소했던 코드가 아래의 코드였다.

<Camera
  ref={ref => {
    this.camera = ref;
    }}
    // ...
</Camera>

ref의 사용을 전혀 몰라서 찾아보았다. 여기로 가면 자세한 설명이 있다.

다음은 리액트 네이티브(React Native), Expo에서 카메라, 갤러리에서 넘어오는 경로를 같은 state에 저장하는 것과 Component Life Cycle에 대해서 공부를 할 차례이다.