저번 다이맥스 어드벤처 목록 사이트 개발 때 느꼈지만,

이런 서비스 개발 과정은 하면서 올려야지 나중에 하려고 하면 귀찮아서 때려치우게 되는 법이다ㅎ

이번 실전배틀 성향 테스트는 개발하면서 개발기를 간단히 남겨보려 한다.


사용 기술

  • Flutter
요즘 내가 공부하고 있는 언어이기도 하고, 웹개발도 지원하는데 기본적으로 반응형 디자인으로 구현되기 때문에 적합하다고 생각했다.

  • Netlify
간단히 사전조사해본 결과, 넷틀리파이라는 웹호스팅 서비스가 있었다. 코드리스에 깔끔하니 좋아보여서 써보기로 했다.

  • Firebase
파이어베이스로 플러터 웹앱을 바로 런칭해버릴 수 있다는 걸 뒤늦게 알게 됐다ㅋㅋㅋ
콘솔에 명령어 몇 줄로 디플로이가 되고 도메인도 엄청 깔끔하게 잘 뽑힌다!

구조

나는 쌩초짜 아마추어이기 때문에 최종적으로 구현할 페이지 위주로 정리하면 다음과 같다.
  • 홈 페이지 (간단한 설명 / 테스트 시작하기 버튼)
  • 테스트 문항 페이지 (이미지(필요하다면) / 선택지 / 이전, 다음 버튼)
  • 결과 페이지 (설명 / 이미지 / 분야별 점수(높음, 보통) / 잘맞는,상극인 유형 / 공유하기 버튼)
기본적으로 인터넷에서 쉽게 찾아볼 수 있는 퀴즈앱 만들기 예제를 참고하면 금방 구현할 수 있을 듯 하다.
공유하기 기능도 플러터 플러그인으로 이미 존재한다. 각 유형별로 결과페이지 하나씩 만든 뒤에 그 페이지를 공유하게 하면 간단할 것이다.


디자인 초안






 검사도구

이번에는 내용적인 부분의 설계.

이런 종류의 검사는 여러 팩터를 설정해서 점수를 부여하고, 그 점수를 토대로 성향을 도출하게 된다.

이 테스트에서 설정하는 팩터는 다음 3가지이다.
  • 숙련도
  • 승부욕
  • 자신감

피검사자들이 직관적으로 그 의미를 이해할 수 있는 단어로 선정했다.
어차피 재미삼아 해보는 것이므로 정확할 리도 없을 뿐더러 하는 사람들도 이 점을 이해해줄 것이다.


검사결과 이 3가지 항목에 부여되는 점수를 각각 상 / 하로 나누고, 이에 따라 2의 3제곱 = 8가지 성향이 도출되도록 한다.

 


원래는 상중하로 세분화하려 했는데, 좀 무의미한 분류가 나오기도 하고 27가지는 아무튼 너무 많았다.
지금의 8가지 패턴이 딱 좋다고 생각한다.


플러터 라우팅 네비게이터 2.0 공부

처음에는 플러터 웹 앱의 URL이 /#으로 고정된다는 것을 깨닫고 꽤 좌절했다.

요즘 온갖 심리테스트, 성향테스트가 유행하는 근원이 무엇이던가?
카톡이며 페북 트위터를 통한 SNS 결과 공유에 있지 않던가.
그러려면 최종 결과 페이지의 링크는 고정된 상태여야 share 플러그인으로 공유하게 하기 편하다.

어쩔 수 없이 결과 페이지만 JS로 구현해야 하는 건가 싶어서 꽤 실망한 채로 웹서핑을 해보니


우리의 신생아 플러터님께서 또 얼마전에 라우팅 기능을 업데이트 하셨다 한다ㅎㅎㅎ
(썸네일의 표정에서 절망이 느껴지는가? 정답이다. 내 얼굴에서도 느낄 수 있을 듯ㅎ)

현재로서 플러터에게 가장 아쉬운 부분이 이것인데
허구한 날 업데이트를 하면서 현존하는 강의영상이며 자료들을 한순간에 구닥다리로 만들어버린다는 것이다ㅋㅋㅋㅋ
이건 아직 미완성이라 어쩔 수 없는 부분이다. 오히려 내가 플러터를 택하게 된 근본적인 이유 중 하나이기도 하고.


다행히 강의 영상이 아주 구체적으로 단계별 설명을 해주고 있었고
내가 준비하는 서비스도 매우 단순하며 정적인 구조로 되어있어서 내 웹앱에 곧장 적용하기 쉬울 듯 하다.


문항이 나오는 부분은 URL 기반 라우팅을 하지 않기로 했다.
고정 URL은 어디까지나 결과공유를 위해서 필요한 것이기도 하고, 사용자가 주소 입력으로 특정 문항으로 진행한다든지 하면 꼬이기 때문.

---------------------------

위 영상을 보며 떠듬떠듬 코딩을 하다가 때려치웠다ㅋㅋㅋ
무려 국내에도 관련 포스팅이 있다는 걸 뒤늦게 발견!
(플러터 웹에 대한 관심이 예상보다 많은 모양이다)

코딩아빠님의 블로그에 정말 잘 정리되어 있다.

덕분에 한 방에 성공시켜버렸다!ㅠ
(물론 주말 오전 5시간을 갈아넣었지만)

코딩아빠님께는 너무나도 감사드릴 따름이다.

프런트엔드 구현

처음에는 라디오박스를 체크한 뒤 다음 버튼을 눌러 넘어가고, 다시 이전 단계로도 돌아갈 수 있는 형태로 구상을 했지만

그냥 이래저래 꼬이기도 하고, 다른 상용 성향테스트앱들도 대부분 이전단계로 돌아가는 기능은 지원하지 않고 있어서 단순한 RaisedButton으로 구현하기로 결정.

화면 내에 컴포넌트 배치하느라 정말 몇 날 며칠을 고생했다.
덕분에 여러가지를 배우게 되어서 참 다행이다.

그리고 한 편으로 이게 플러터가 아니라 JS + CSS였다면 어쩔 뻔 했나.. 싶기도 하다ㅋㅋ
프런트엔드 구현에 있어서는 정말 플러터가 직관적이고 좋다고 생각한다. (물론 나 같은 입문자 한정)



많은 삽질 끝에 아주 깔끔해보이는 결과물이 나왔다.
물론 알맹이는 스파게티다.


이미지 제작

이렇게 간단한 앱에 들어가는 이미지가 이렇게나 많다니..






 asMap이 먹통이 되는 희한한 문제 발생ㅠ

정말 에러 없는 세상에서 살고 싶다..



이렇게 화면 전체가 표시되지 않는 현상이 생기는데
코드 상으로도 전혀 문제가 없고 스크린을 한번 닫았다 열면 정상 표시가 되는, 정말 요상하면서도 대처가 안되는 에러가 생긴다ㅠ
심지어 어떤 경우에는 정상 동작이 되기도 하고..
맥북으로 옮겨서 해봐도 동일한 문제가 발생한다ㅠㅠ

가장 악질적인 점은 구글링을 해봐도 마땅한 해결법이 안 나온다는 것ㅠㅠ
(플러터 SDK 업데이트를 하라느니 dev 채널로 바꾸라느니 하는 조언들이 있었지만 다 안 통함)

그래서 그냥


창을 열었다 닫았다 열어주기로 했다ㅋㅋㅋㅋ
도중에 텀이 없으면 에러가 반복 돼서, 500 밀리세컨드 정도 딜레이도 줬다ㅋㅋㅋ

꼼수로 문제 해결하는 능력만 성장하는 중



그리고 어느 날 자려고 누웠다가
'??? 굳이 asMap을 써서 리스트를 맵으로 변환할 필요가 없는데???'
라는 생각이 번뜩 들어서

다음 날 아침 asMap을 전부 빼줬더니 문제가 해결돼버렸다ㅋㅋㅋㅋ

코린이라서 예제에 있는 그대로 아무 생각 없이 asMap을 따라 적어서 생긴 해프닝..
csv를 리스트로 변환하는 과정에서 텀이 발생하는데, 그 동안에 asMap을 통해 null을 맵으로 변환시키려 하니 문제가 생길 수 밖에.


왜 나는 깜빡했나 이진법을....

얼추 사이트 완성을 해가던 시점에 깨달은 것이 있다.


이 앱은 숙련도 / 승부욕 / 자신감 3가지 항목을 채점해서 결과를 뽑는다.
각 문항의 선택지마다 숙련도 / 승부욕 / 자신감 수치 증감량을 설정해서 사용자가 이를 선택하면 반영하는 방식.

그리고 점수를 최종적으로 변환해서 일정 이상을 넘으면 <높음>, 그렇지 못하면 <보통>으로 한다. (위 원그래프들은 실제 유저의 점수를 그대로 반영한 게 아니다. <높음> 값이 나왔으면 초록색으로 80% 정도 채운 그래프가, <보통>이면 파란색의 60% 정도 채워진 그래프가 나올 뿐) 

그러면 사용자의 최종적인 점수는 111, 010, 001 하는 식으로 나타난다.
위 이미지의 토게피 유형은 숙련도: 보통 / 승부욕: 보통 / 자신감: 높음 이니까 001이다.


그런데 이러한 사용자의 점수를 최종 결과 페이지 및 URL 값으로 전달할 때, 나는 참으로 희한한 방법을 썼었다.

  final List<List<int>> decodeMap = [
    [1, 1, 1],
    [1, 1, 0],
    [1, 0, 1],
    [1, 0, 0],
    [0, 1, 1],
    [0, 1, 0],
    [0, 0, 1],
    [0, 0, 0]
  ];

이런 리스트의 리스트를 만들어서 숫자를 변환했던 것..


왜 나는 0과 1을 보면서도 이진법을 떠올리지 못한 거냐!!!

비록 다트 자체적으로 이진법-십진법 변환하는 함수를 제공하는 것 같지는 않지만, 저걸 손보는 건 어렵지 않다.
4로 나눴을 때의 정수 부분 / (4보다 클 경우 4를 뺀 뒤) 2로 나눴을 때의 정수 부분 / 2로 나눴을 때의 나머지를 확인하면 0 또는 1을 도출 할 수 있다.


문제는 이걸 너무 막바지에 발견했다는 것...
코드만이 아니라 이미지며 html이며 다 바꿔야 됨....

물론 극소규모 프로젝트이고 아무도 이걸로 뭐라할 사람은 없지만
오히려 그렇기 때문에 연습삼아 바꿔보고 싶다.
내 스스로 내 코드가 못 생겨서 못 견디겠으니.

날 잡아서 진득하니 손 봐야겠다.



SEO


구글은 어째서인지 파이어베이스 호스팅 기본도메인의 DNS며 설정을 직접 건드릴 수 없게 되어 있어서 웹마스터 도구에 등록시키는 건 일단 보류했다.
물론 커스텀 도메인을 지원하므로 추후 등록하기로 했다.

우선은 네이버 웹마스터 도구에 등록을 해봤는데


나름 열심히 index.html을 건드려줘도 끝끝내 페이지 제목만은 바꾸지를 못하고 있다ㅠ
최초에 웹앱 접속을 할 때에는 정상적으로 내가 입력한대로의 페이지 제목이 뜨는데, 그 직후 뭔가 리디렉션 같은 것을 거치면서 그냥 파이어베이스 프로젝트명으로 제목이 바뀐다.

파이어베이스 호스팅에서 강제로 프로젝트명이 되게끔 간섭하고 있는 걸까?
구글링을 잠깐 해봤지만 별로 나오는 것도 없다..

물론 널리 이 웹앱을 홍보할 마음은 그다지 없다.
하지만 이 사이드 프로젝트의 본 취지가 코딩연습에 있는 만큼, SEO까지 확실하게 해두고 싶었는데ㅠ


아무래도 파이어베이스의 기본도메인이 벌인 농간 같다는 생각이 들어서 커스텀 도메인을 연결한 뒤 시도했더니




올그린!
.ga는 가봉의 국가 최상위 도메인이다. FreeNom에서 무료로 등록할 수 있고 예전에 자작NAS 처음 만들던 시절부터 애용해왔다.

물론 위의 일부 내용은 바뀐 도메인에 맞게끔 수정해줘야 할 것 같다.
우선은 자축ㅋㅋ 내 문제 해결능력은 꽤 나쁘지 않은듯 하다ㅎ
가끔은 자아도취도 좀 해줘야 된다.
완전한 비전공자 치고는 스스로 기계 다루는 센스가 좋다고 생각한다. 어느 단에서 문제가 발생하는지 꽤 금방 깨닫는 편.