본문 바로가기

프로젝트/뉴스 매니저 - 직관적인 뉴스 관리 앱

[App] 뉴스 매니저 출시

이번엔 1등 오답노트의 베이스가 되었던 뉴스 매니저라는 앱과 제작 후기를 소개해 보려고 합니다.

 

 

뉴스 매니저

정말 쉬운 뉴스 관리 앱.직관적인 뉴스 관리 App. 스크랩한 기사를 한 눈에 확인할 수 있습니다. 자주 찾는 언론사를 즐겨찾기에 추가해 보세요. 내가 활동한 내용을 한 눈에 확인할 수 있어요. 나

xn--vg1b7f65r8vjcwg.kr

뉴스 매니저 소개

  • 구글 Keep을 뉴스 스크랩 앱으로 재구성했고, 여기에 소셜 기능을 추가했습니다.
  • 다른 뉴스 앱보다 시각화와 북마크 기능에 중점을 두었습니다.
  • 내부 브라우저에서 사용자가 자주 찾는 언론사를 즐겨찾기에 추가하고, 맘에 드는 기사를 요약 정보와 함께 스크랩하여 메모 형태로 저장해 주는 유틸리티입니다.
  • 버튼은 왠만하면 아래에 배치하였고, 개수를 최소화했습니다. 앱 UI보다 사용자의 컨텐츠를 최대한 많이 보여주기 위해 노력했습니다

 

백앤드

  • NodeJS에서 동작하는 GraphQL 서버입니다.
  • 소셜 기능을 구현하기 위해 관계형 데이터베이스를 사용했습니다.
  • 관계형 데이터베이스는 Prisma를 사용해서 구현했습니다.
  • 당연히 HTTPS로 통신하고, SSL 인증서 생성, 서버 생성 및 배포 자동화를 위해 도커와 스크립트를 사용했습니다.
    (참조: https://joondong.tistory.com/164

보안

  • 스크랩 기사는 react-native-async-storage가 아닌 react-native-secure-key-store를 사용하여 저장합니다.
  • 사용자의 정보는 최소한만 사용합니다. 소셜 로그인할 때는 이름과 OAuth 공급자(구글, 카카오 등)가 주는 ID만 받아옵니다. 이메일도 받아오지 않습니다.
  • 이름은 사용자가 스크랩을 공유했을 때 누가 공유했는지 표시하기 위해서, ID는 데이터의 소유권을 확인하기 위해서 사용됩니다.
  • 사용자가 다른 기기로 스크랩 데이터를 옮기기 위해 데이터를 서버 백업하면 암호화되어 업로드됩니다. 그래서 저도 확인할 수 없고, 비밀번호 분실시 복구되지도 않습니다.
  • 백업 데이터는 한 시간 후 자등으로 삭제됩니다.
    (참조: https://joondong.tistory.com/173)
  • 내부 브라우저의 시작 페이지는 언론사를 모아놓은 자체제작 사이트인데, 이 사이트를 만들 때 우리나라 언론사의 절반 이상이 아직 HTTP를 사용하고 있다는 사실을 알았습니다. 그래서 HTTP 권한이 포함되어 있는데, 이것때문에 제한연령이 17+가 되었습니다

이외

  • 앱스토어에서는 소셜 기능이 포함되면 사용자를 차단하는 기능, 욕설을 필터링하는 기능이 추가되어야 한다고 해서 승인을 받지 못했었습니다.
  • badwords 라이브러리를 사용해서 욕설을 필터링했습니다

주요 컴포넌트

REACT NATIVE PAPER

  • 일반 버튼, 리플 버튼, 로딩바, 카드(그림자 효과) 및 메뉴에 사용했습니다.
  • 화려하지 않으면서 감각적인 디자인이 마음에 들었습니다

REACT NATIVE WATERFALL

  • Keep의 보기 방식을 재현하기 위해 사용한 라이브러리입니다.
  • 높이가 미리 결정되어야 하는 것이 특징입니다.
  • 1등 오답노트는 이미지를 표시하기 때문에 이미지 비율 기준으로 결정하면 됐었는데, 뉴스 매니저는 텍스트를 표시하기 때문에 예상되는 텍스트 라인수를 결정하기 까다로웠습니다.
  • 그리고 안드로이드에서는 Fresco때문에 이미지가 깨져보이는 현상이 나타나서 FastImage를 사용했는데, 삭제, 수정, 라인수 변경 등으로 아이템들이 재배열될 때, FastImage에서 캐시 이미지를 인식하지 못하는 문제가 있었습니다.
  • 위 두개 기능을 자연스럽게 보이도록 해결하는데 상당히 애를 먹었습니다. (거의 전체 작업의 50~60%)
  • 이 라이브러리는 ScrollView를 기반으로 합니다. 스크롤 위치에 따라서 화면에 보이는 아이템을 빼고 넣고를 반복하기 때문에 성능 이슈가 있습니다. 그래도 그냥 ScrollView를 사용하는 것보다는 훨씬 빠릅니다.
  • 아이폰6S와 넥서스5X에서 스크랩 기사가 많을 경우 약간 버벅거리는데 쓸만한 수준은 됩니다.
  • 최근 2-3년 중급형기기 이상에서는 무리없이 작동할 것 같습니다

REACT NATIVE REANIMATED

  • 알게 모르게 소소한 애니메이션이 많이 적용되었습니다.
  • V1은 사용해보지 않아서 모르겠지만, V2는 사용하기 쉽고, 속도도 빨랐습니다

REACT NATIVE APOLLO

  • GraphQL 클라이언트 라이브러리입니다.
  • 이 라이브러리의 가장 강력한 기능은 캐시 관리 기능입니다.
  • 이전 요청에 대한 응답을 자동으로 캐싱해 두었다가 나중에 동일한 요청이 발생하면 캐시 데이터를 사용해서 바로 응답하고, 서버에서 최신 데이터를 받아오면 업데이트해 주는 기능이 포함되어 있습니다.
  • 하지만 캐시 기능은 양날의 검...?까지는 아니고 장점이 있으면 단점도 있는 법.
  • 뉴스 매니저에는 내가 쓴 댓글과 좋아요/싫어요 표시한 다른 사용자의 스크랩을 목록으로 보여주는 기능이 있는데, 댓글을 삭제하거나 좋아요를 취소한 경우, 다음에 동일한 스크린에 접근했을 때, 캐시 데이터가 그대로 표시되는 문제가 있습니다.
  • 서버에서 삭제했더라도 Apollo는 그것을 인식하지 못합니다. 직접 해당 요청에 대한 캐시 데이터를 찾아서 삭제해 주었습니다.
  • 서버에 요청을 할 때도 한 번에 모두 요청하는 것이 아니라 스크롤 위치에 따라 10~20개씩 요청하기 때문에, 모든 요청에 대해 이런 처리를 해 줍니다. 몇 번째 요청에 대한 캐시 데이터에서 변화가 발생할지 모르니까 말이죠.
  • 사용자는 당연히 그렇게 되어야 한다고 생각하는 것도 막상 구현하려니 상당히 까다로웠습니다.
  • 가장 쉬운 방법은 캐시를 사용하지 않는 것이지만, 개발자로서 한 번 시도해 보고 싶었습니다.
  • 나중에 제 블로그에 이 방법은 따로 포스팅할 계획입니다

REACT NATIVE FBADS

  • 애드몹은 광고 제한이 너무 심해서 페이스북으로 갈아탔습니다. (실제 광고가 수신되는지 테스트 할때 테스트 기기 등록을 잠시 해제했는데 바로 정지먹이더군요. 심지어 No-fill 오류로 광고가 수신되지도 않았는데도 불구하구요.)
  • 애드몹 배너는 이미지인데 페이스북 배너는 반응형이라서 보기 더 좋네요.
  • 그리고 전면 삽입 광고도 더 매력적으로 보였습니다.
  • 그런데 iOS에서 KeyboardAvoidingView와 함께 사용하면 상태바 높이 변화 이슈가 발생합니다.
    저는 이것을 상태를 통해 해결했습니다.
    (참조: https://github.com/callstack/react-native-fbads/issues/291)
  • [+] 광고 품질 자체는 페이스북이 더 좋긴 한 것 같은데 페이스북이 설치되어 있는 앱에서만 광고가 표시되기 때문에 다시 애드몹으로 바꾸고 있습니다.

REACT NATIVE HOLEVIEW

앱 처음 실행시 사용 방법을 설명할 때 버튼의 위치를 강조하기 위해 사용했습니다.

(참조: https://joondong.tistory.com/175)

 

REACT NATIVE RECEIVE SHARING INTENT

앱에서 다른앱으로 공유하는 것이 아니라, 다른 앱에서 공유를 받기 위해 사용한 라이브러리입니다.

iOS에선 내부에서 공유를 받는 하위 앱을 새로 만든다는 것이 특이했습니다.

계획

메모를 벽돌 형식으로 한 눈에 보여주는 기능이 유용하긴 하지만 구글 Keep의 다운로드 횟수가 1억건 이상 될 수 있었던 것은 다양한 플랫폼에서 동기화되는 기능 덕분이었을 것입니다.

 

처음에는 뉴스 매니저도 그렇게 만들었습니다. 그런데 만들고 보니 뉴스 스크랩이라도 누군가에게는 일기가 될 수 있다는 생각을 했습니다. 아마도 구글 Keep은 서버에 저장된 데이터에 암호화 기술이 적용되어 있을 것입니다. 그래서 일단은 즐겨찾기와 사용자가 공유하지 않은 스크랩이 서버로 올라가는 코드를 모두 삭제했습니다.

 

너무 아까웠습니다. 아래 동영상에 중반부에 나와있지만 오프라인 상태에서도 수정된 상태를 기억해 뒀다가 나중에 온라인 상태가 되었을 때 업데이트 날짜 비교해서 동기화시키는 기능까지 삭제하고 수정했거든요.

 

다행인 것은 백업/복구 기능에 암호화를 적용했다는 것입니다. 사용자가 백업한 데이터는 즐겨찾기 및 스크랩 단위로 암호화되어 DB에 저장됩니다.

이 기능을 응용하면 즐겨찾기와 사용자가 공유하지 않은 스크랩도 안전하게 서버에 저장하고 가져올 수 있을 것입니다. 다만, 앱 반응과 서버 부담을 고려하여 추후에 추가할 계획입니다.

 

암호화되어 서버에 저장된 백업 데이터