neoman-omyeon-go / Bigsasimi_FrontEnd

'Young Yang Gang' Frontend Main Repository(Flutter)
1 stars 1 forks source link

FrontEnd

API 공통

Flutter 의 특징으로 비동기 작업의 결과를 나타내며, 미완료 또는 완료의 두 가지 상태를 가질 수 있다.
(비동기의 특징으로써, 작업의 결과를 기다리지 않고 바로 다음 작업으로 넘어감. 후에 작업이 완료되면 결과를 받는 방식으로 비동기를 처리함.)

  1. 미완성: 값을 만들어 내기 전의 Future 상태이다.
  2. 완료: 비동기 작업이 성공하면 Future는 값을 완성함. 작업이 실패할 경우 에러.
    사용자 입장에서 답답함을 느끼지 않게 하기위해서, 프런트는 서버로 Request를 보내는 모든 API는 비동기 처리를 하였다.

    Post 와 Get 의 차이에 따라 전송하는 데이터의 유, 무가 존재하지만, Post, Put 의 경우에는 전송할 데이터를 Map 으로 구성하여 Flutter 의 API 처리 라이브러리인 Dio 패키지를 사용하여 API Request 를 전송하였다.

    모든 API Request 의 구성은 API 의 종류(Post, Get, Put 등..)를 가리지 않고 try – catch 문으로 try 에서 성공되지 못한 결과에 예외처리를 두어서 사용자에게 피드백 되도록 구현했다.
    상태코드 200 이 반환되었을 경우는 Response 의 값을 해당 데이터 필요한 class 에 저장시켜 각 페이지별로 분리하여 Model 을 만들어 관리하였다. 200 이 아닌 다른 상태코드가 반환되었을 경우 예외처리를 두었고, 대부분 사용자에게 피드백이 가도록 구현하였다.

로그인 & 회원가입

로그인의 경우 비동기 처리를 사용하여 사용자의 아이디와 비밀번호를 입력하고, 이를 Map 으로 구성하여 API Request 를 전송하였다. 상태코드 200 이 반환되었을 경우는 Response 의 값으로 반환되는 jwt 의 Access 토큰과 Refresh 토큰을 Flutter 의 중요 데이터 보관 객체인 FlutterSecureStorage 라이브러리를 사용하여 이곳에 저장하였다. 로그인 이후에 사용되는 모든 API Request 는 access토큰을 반드시 Header에 동반되어 전송해야 한다.

회원가입도 비동기 처리를 사용하여 사용자가 원하는 아이디와, 비밀번호 그리고 Email 을 기입하여 회원가입을 진행할 수 있다. 이때, 중복되는(이미 존재하는) 아이디가 존재하면, 사용자에게 “중복된 아이디” 라고 피드백을 보여준다.

프로필

프로필 페이지가 사용자에게 보여지기 이전에 즉, 페이지가 렌더링 되어지기 이전에 로딩 프로그레스 바를 만들어두어, 로그인 성공시 FlutterSecureStorage 안에 저장되어 있는 유저의 ID 를 읽어온다. 이 후, 해당 ID 의 정보를 불러오는 API 를 전송하여 사용자의 정보를 관리하는 class 를 initializing 시켜서 렌더링을 시작한다. Late 키워드를 사용하여, 지금 즉시 초기화되어야 하는 데이터를 늦은 초기화를 가능케 하면서, 로딩 프로레스바로 데이터가 불러와짐을 보장했다. 대부분의 페이지에서는 위와 같은 초기화 단계 수행 보장 과정을 통해 데이터를 로딩한다.

사용자가 기입하는 TextField 에 원하는 정보를 기입하고 우측 상단에 있는 ‘저장’ 버튼을 클릭하게 되면, API 의 명세에 부합하게 타입을 변환하거나 파싱하여 Map으로 감싸서 API Request 를 보내게 된다. API Request가 성공하게 되면, 하단의 스낵바를 통해 성공의 피드백을, 실패시 실패의 피드백을 제공한다. 성공 이후, 바뀐 사용자의 데이터는 setState 를 통해 상태 업데이트를 진행하였다. 이로써, 변화된 정보에 대해 사용자는 즉각적으로 알아차릴 수 있다.

프로필 페이지에 보여지는 여러 Widget 들은 재사용성을 높이기 위해 컴포넌트로 구성하여 파일로 관리했다.

오늘의 영양 섭취 그래프

사용자가 금일 섭취한 영양정보에 대해 관리하는 class가 따로 존재한다.
해당 class 에서 정보를 불러와 객체화 시킨 이후, 데이터들을 initState 를 통해 렌더링 한다. ‘오늘의 영양 섭취 그래프’ 페이지는 두 가지의 형태를 갖는다. 우측 상단에 존재하는 토글(차트, 리스트 아이템) 버튼을 클릭하여, 차트로써 직관적으로 한 눈에 볼 수 있고, 리스트 아이템으로써 자세하게 볼 수 있다. 이는, 버튼의 클릭 시 bool 변수로 관리되어 토글 기능을 수행한다. 각 버튼을 눌렀을 때 렌더링 되는 위젯들을 각각 만들어 한 페이지에서 보여주도록 구현했다.

캘린더 – 데일리 그래프, 데일리 섭취 히스토리

DateTime 객체를 사용하여 날짜를 사용할 수 있게 만들었다. 기본적으로 현재 날짜를 불러와 initalizing 이 이루어지고, 사용자는 원하는 날짜를 선택하여 해당 날짜에 섭취한 영양정보를 그래프로 볼 수 있고, 하단의 버튼을 클릭 시 더 정확한 섭취 히스토리를 볼 수 있게 구현하였다. 이 때, 날짜를 선택할 때 로딩 프로그레스바를 배치하여, 데이터가 불러옴을 보장하였다.

이미지 업로드 및 영양정보 추출

‘영양갱’ 프로젝트의 핵심 기능인 업로드 부분이다. food.dart 의 클래스는 음식에 대한 모든 데이터를 관리하는 class 로 칼로리, 단백질, 지방, 탄수화물, 콜레스테롤, 당류를 관리한다. 그리고 이를 바탕으로 4가지 기능을 제공한다.

수동기입

사용자가 기입한 영양정보 데이터를 즉시 서버로 전송하고, 피드백을 보여준다.

검색기입

검색어 입력 시 미리 정의된 DB 에서 데이터를 불러와 List타입으로써 관리했다. 특히 사용자가 검색어를 입력할 때 마다, 가장 유사한 음식 이름을 상위에 노출시켜 보다 빠르고 편리하게 검색이 가능하게끔 구현하였다.

사진 선택 기입

AndroidManifest.xml 파일에 사용자 기기의 갤러리 접근에 권한을 얻도록 설정했다. 이 후, 갤러리에서 영양정보 테이블을 선택하여 서버로 전송할 수 있다. 하지만, 영양정보 테이블이 아닌 사람 얼굴, 풍경 과 같은 엉뚱한 사진을 전송하면 200 이 아닌 다른 상태코드가 나오며, 명세서에 정의된 대로 “인식할 수 없는 사진” 이라는 피드백을 제공한다. 정상적인 사진을 기입할 경우, 200 의 상태코드가 반환되는 동시에 영양 정보를 Response 로써 전달받고, 이를 사용자에게 한번 더 확인할 기회를 부여함으로써 더욱 더 정확한 정보가 기입됨을 보장하였다.

사진 촬영 기입

‘사진 선택 기입’과 같이 Manifest 파일에서의 사용자 카메라 사용 권한 승인을 받는다. 사진을 촬영한 이후의 과정은 ‘사진 선택 기입’ 과 같은 작동 방식이다. 서버에 업로드 하는 API 는 위의 4 가지 기능이 전부 같은 API 를 공유한다. 입력의 방식이 다를 뿐이지, 결국 업로드 되는 데이터는 완전히 같은 정보이기 때문이다.

사용자가 제품 영양정보 테이블 촬영 후, 테이블이 자리하는 영역을 직접 사용자가 잘라서 전송할 수도 있었다. 그러나, 사진 촬영 한 번만으로 모든 작업을 끝내는 단순한 workflow 를 만들고자 Object Detection 의 AI 기능을 사용하여 보다 편한 기능 설계를 추구하였다. 또한 업로드한 정보들은 즉각적으로 사용자의 섭취 영양 정보 Class와 공유되어 바로바로 반영된다.

오늘의 뉴스

오늘의 뉴스 페이지는 MVVM 패턴을 사용하였다. 이를 위해 Flutter 의 인기 라이브러리인 Provider 패키지를 사용했다. news.dart 페이지는 model 로써 역할을 수행한다. 뉴스의 포함된 데이터를 정의하고 관리한다. news_providers.dart 는 newsapi.org 에서 발급받은 API key 를 사용하여 반환받은 결과값을 알맞은 변수로 파싱해여 저장하고, news.dart 모델에 제공하기위한 파일이다. 이후, Viewmodel 인 todaysNews.dart 와 news_detail_screen.dart 파일로 provider 가 제공하는 정보를 news라는 모델로 받고 보여지게 된다.

주변 식당

‘주변 식당’ 페이지는 UI 는 작성하였으나, 기능이 아직 구현되지 않았다. 프런트에서 구현한 기능에 대해서만 서술하겠다. Naver Map API Key 를 발급받아 flutter_naver_map 패키지의 NaverMapController 객체를 생성했다. 사용자의 위치 정보를 받아오기 위해 Manifest 파일의 위치 권한을 부여받게 설정하여, 위도와 경도 좌표를 가져오게 된다. 이를 initState 시 고정시켜서 사용자가 머무르는 위치를 보여준다.