본문 바로가기
FE Development/React-Native

트러블 슈팅 - ReactNative http request 중 백그라운드 전환시 Network Error

by 개발자 데이빗 2021. 11. 11.

문제가 되었던 사항

특정 정보를 등록하는 api 요청시 응답시간이 최대 1분가량 걸리는 상황

안드로이드의 경우 문제가 없었지만 ios에서 문제가 발생했다.

api 요청을 보낸 후 백그라운드 진입시 요청 cancel 되어 포그라운드 재진입시 네트워크 에러가 반환된다.

사용된 라이브러리

https://github.com/ivanzotov/react-native-begin-background-task

해결 과정

접근 방식

서버 개발자와 해당 이슈에 대해 소통한 결과 안드로이드의 경우 앱이 종료된 경우 cancel과 관련되어 보이는 요청을 보내는데 ios의 경우 백그라운드 진입 또는 앱이 종료된 경우 모두 해당 요청을 보내는 것을 확인하였다.

해당 요청을 보내 network error가 반환이 되어도 서버단에서는 해당 api를 실행하여 DB에는 원하는 특정 정보가 정상적으로 저장되는 상황이다.

앱이 종료된 경우 다시 실행하면 정상적으로 등록된 정보(앱에서는 특정 요청을 보냈지만 서버에서는 정상적으로 DB에 저장하였으므로)를 서버에서 불러오지만 

백그라운드 -> 포그라운드 전환시에는 에러를 반환하여 알럿이 표시되고 재등록을 시도하면 이미 등록된 정보로 재등록이 불가능한 상황이었다.

앱을 종료하는 경우는 신경쓰지 않고 백그라운드 전환시 network error가 반환되는 부분에 집중하기로 하였다.

 

이슈서칭

React Native github에서 관련된 이슈를 찾아보았으나 해결방법은 찾지 못했고 관련한 PR 요청을 발견했다.

아쉽게도 몇몇 테스트 코드를 통과하지 못한것으로 보인다.

https://github.com/facebook/react-native/pull/31838

 

Allow network requests to finish when app is sent to background by maxkomarychev · Pull Request #31838 · facebook/react-native

Summary This change allows network requests to be executed in background safely. In certain conditions iOS HTTP requests are being terminated with this error: Error Domain=NSURLErrorDomain Code=-10...

github.com

React Native의 백그라운드 태스크에 관한 정보 서칭 중 아래 블로그에서 관련된 글을 발견하였다.

과거 ios에서는 백그라운드 태스크에 관해 비교적 엄격했지만 오늘날에는 안드로이드와 비슷한 수준이라고 한다.

해당 블로그에서는 추천하는 라이브러리를 사용하기로 한다.

https://codeburst.io/the-definitive-guide-to-react-native-background-processing-51df02540433

 

The definitive guide to React Native background processing

Many apps would require some kind of background processing for various tasks like finishing a download or checking for something while in…

codeburst.io

 

해당 블로그에서 추천하는 라이브러리 사용 시 이슈가 있었다.

라이브러리 링크 후 빌드를하면 React/RCTDefines.h not found 에러와 함께 빌드가 되지 않는 문제였는데

다행히 해당 라이브러리 깃헙 이슈에 관련된 이슈가 올라와 있었다.

문제가 되는 import 구문을 아래와 같이 수정하여 해결하였다.

#if __has_include("RCTDefines.h")
  #import "RCTDefines.h"
#else
 #import <React/RCTDefines.h>
#endif

https://github.com/ivanzotov/react-native-begin-background-task/issues/2

 

React/RCTDefines.h file not found · Issue #2 · ivanzotov/react-native-begin-background-task

After linking, I'm getting the following build error: React/RCTDefines.h file not found Linking did not add anything to my podfile so not much for me to tweak. Any help would be appreciated.

github.com

기존 코드 예시

const registerSomething = (dispatch) => async (something) => {
  try {
    dispatch({
      type: 'register_something',
      payload: {
        loading: true,
      },
    });

    const response = await requestRegisterSomething(something);
    dispatch({
      type: 'register_something',
      payload: {
        loading: false,
        response,
      },
    });
  } catch (e) {
    dispatch({
      type: 'register_something',
      payload: {
        loading: false,
      },
    });
    handleError(e);
  }
};

해결 결과

xcode에서 프로젝트 target의 Signing & Capabilities 탭에 Background Modes에서 Background fetch, Background processing을 체크한다.

react-native-begin-background-task 라이브러리를 활용하여 문제가 되었던 api 요청 시작시 백그라운드 태스크를 열어주고 해당 작업이 끝난 후 태스크를 닫아줌으로써 해결하였다.

특정 api가 아닌 모든 api요청에서 사용하려면 http request를 util 함수로 만들어 모든 요청마다 태스크를 열고 닫으면 될 것 같다.

해결 결과 코드 예시

import { beginBackgroundTask, endBackgroundTask } from 'react-native-begin-background-task';

const registerSomething = (dispatch) => async (something) => {
  const backgroundTaskId = await beginBackgroundTask();
  try {
    dispatch({
      type: 'register_something',
      payload: {
        loading: true,
      },
    });

    const response = await requestRegisterSomething(something);
    dispatch({
      type: 'register_something',
      payload: {
        loading: false,
        response,
      },
    });
  } catch (e) {
    dispatch({
      type: 'register_something',
      payload: {
        loading: false,
      },
    });
    handleError(e);
  }
  await endBackgroundTask(backgroundTaskId);
};

 

아쉬웠던 점

도움이 되었던 블로그에 따르면 해당 라이브러리를 사용해 백그라운드에서 요청을 유지해도 30초 동안만 유지가 된다고 한다.

문제가 되었던 api의 경우 대부분 10~15초 이내로 응답이 오지만 스크랩핑을 이용하기 때문에 드물지만 최대 1분까지 걸리는 경우가 있다.

이러한 경우 전과 동일하게 network error가 발생할 것으로 예상된다.

또한 사용된 라이브러리의 마지막 커밋이 2019년으로 현재 관리가 되지 않는 점이 불안한 요소이기도 하다.

native 관련 지식과 native module 제작에 대한 필요성을 느꼈던 이슈 해결과정이었다.

댓글