22.08.04 TIL

옵주비·2022년 8월 5일
1

내일은 발표 바로 전날이라 리허설도 있고, 준비할 것도 있고 하다보니 '나만의 무기 TIL'은 오늘로 마무리하게 될 것 같다. 만감이 교차하는데, 5주에 대한 회고는 발표가 끝난 이후의 새로운 개발일지에서 자세히 적어보도록 하겠다 😙

(글을 작성하고 있는 '내일'(==금요일) 현재, 예상은 틀리지 않았다...! )

나만의 무기 만들기

어제 팀 차원에서의 개발은 마무리하고, 오늘은 개인적으로(?) 몇 가지 작업을 해보았다. 일부는 실제로 dev에 반영해서 빌드도 했으니, 개발의 연장선이라 봐도 무방하겠지만 :) 어제 저녁에 추가적으로 하면 좋을듯한? 작업들을 정리해놓은 리스트인데, 보다시피 체크리스트는 다 완성을 했다. HTTP -> HTTPS로 변경하는거 외에는 모두 내가 작업했는데, 하나하나 간단히 정리해보도록 하겠다.

명함 수락거절 멘트 수정

기존에는 명함이 도착하면 반가워요! 누구세요? 라는 문구가 떴는데, 멘토님께서 이 문구를 수정하는 것이 어떻겠냐는 피드백을 해주셨다. 직관적이지 않다는 이유에서였는데, 그래서 고민 끝에 수락해요, 거절해요 로 변경해주었다.

QR교환 유효하지 않은 QR인식 처리

이 부분은 리스트업을 해논 직후에, 어제 해결하고 정리해두둔 부분이다. 보내는 사람은 소켓방의 이름을 utf-8 인코딩과 base64 인코딩을 거쳐 ASCII 코드로 암호화시켜서 QR코드를 생성하도록 하였고, 받는 사람은 디코딩을 통해 네모 앱에서 발행한 유효한 QR코드인지 검증한다. 자세한 사항은 이전 글인 22.08.03 TIL에서 확인이 가능하다 :)

그러고보니 너무 개발일지 이름을 날짜-TIL 형식으로 쓴거 같다. 최종발표 이후에 여유가 생기면 제목들을 좀 더 내용에 맞게 바꾸는 것을 검토해봐야겠다 🤔 Flutter로 앱 개발을 하는 사람들이나 Node.js를 활용해 서버를 구축하고 DB 연동을 한 사람들이 참고할 수 있도록..! 사실 Velog가 도메인 노출이 잘 되지 않아서 다른 사람들에게 도움이 되고싶다는 나의 욕구를 완벽히 채워주지 못하고 있기에, tistory로 옮겨갈까도 진지하게 고민 중이다.

연락처(명함첩), 메세지 서치바 수정

원래는 서치바에 영어를 입력할 때, OPJOOBE를 찾기 위해 소문자 o를 입력하면 검색이 되지 않았다. 정확히 입력하는게 맞지 않나라는 취지에서였는데, 시연하는 팀원들도 가끔 소문자 o를 썼다가 다시 대문자로 바꾸기도 하는 모습을 보니 사용자 입장에서도 굉장히 불편할 것 같았다.

그래서 연락처와 메세지에 있는 서치바에서 영문자는 대소문자와 상관없이 잘 검색이 되도록 바꿔주었다. 이를 위해서는 1) 검색 키워드를 입력할 때와 2) 실제 데이터에 대해서 필터를 해줄 때의 2가지 경우 각각에 .toLowerCase()를 적용해주면 된다.

만약 '난JooBe24' 라는 아이디가 있다면, '난joobe24'에서 영문자(joobe) 대소문자를 어떻게 치든간에 잘 검색해낼 수 있게 된다.

/* 1) 검색어에 .toLowerCase() 적용 */

TextField(
	controller: _controller,
	onChanged: (text) async {
		searchContacts(text.toLowerCase());
	},
    ...
)

/* (2) 실제 데이터를 걸러낼 때도 .toLowerCase() 적용 */

searchContacts(text) {
    setState(() {
      friends = friendsStash
          .where((x) => friendsData[x].nickname.toLowerCase().startsWith(text))
          .toList();
    });
  }

아래 예시는 간단히 'o'를 입력하든 'O'를 입력하든 알파벳 o로 시작하는 아이디들을 잘 검색해내는 것을 보여준다.

위도(lat) 및 경도(lng) 누락으로 인한 connection 버그

살펴보니 오래된 핸드폰의 경우엔 '툭' 쳐서 상대방 명함을 수락할지 결정하는 화면(sharing_accept_page.dart)까지는 잘 오는데, 거기서 '수락해요'를 눌러도 친구로 등록하는 connection POST에서 에러가 났다. 확인해보니 현재 위치가 늦게 잡히거나, GPS를 사용할 수 없는 경우로 인해 lat, lng 값이 초기화 값인 ''로 잡혔기 때문이었다. 위와 같이 not null로 설정해놓은 lat와 lng가 DB에 저장을 위해 날라온 쿼리에는 빈 값으로 들어오니까 fail이 뜨는 것이었다. 따라서, 혹시나 현재 위치를 잡지 못한 경우에 명함 교환을 하는 경우에도 일단 친구 추가가 잘 이루어지도록 조치를 해주었다.

안전하게 FE에서도 예외처리를 해주고, BE에서도 예외처리를 한번 더 해주었다. 각각 빈 값이 들어오면 특정 위도 및 경도를 부여하는 방법이라고 보면 된다. (참고로 이 값은 동해바다의 좌표값이다. 일본해가 아니라 동해가 되길 바라는 마음에서..🇰🇷 바다 한가운데로 설정한 이유는, GPS 없이 교환한 것임을 나타내기 위함이다.)

FE 쪽에서의 처리 (안전장치 1)

latlng가 빈 값인 경우에는 동해바다 좌표를 부여하고, isRightGPS는 false가 들어가게 된다. 이러한 경우에는 명함은 정상적으로 추가하는 대신에, 그 직후에 GPS 정보가 없어서 아쉽다는 스낵바를 띄워줌으로써 사용자에게 고지해주도록 하였다!

saveFriend() async {
    String nowLat = widget.latlng![0].isNotEmpty
        ? widget.latlng![0]
        : '39.74023'; // East Sea Lat
    String nowLng = widget.latlng![1].isNotEmpty
        ? widget.latlng![1]
        : '134.33323'; // East Sea Lng
    bool isRightGPS = widget.latlng![0].isNotEmpty;
    var uri = Uri.parse(
        'http://34.64.217.3:3000/api/friend?id_1=$myId&id_2=${widget.friendId}&lat=$nowLat&lng=$nowLng');
    var request = http.MultipartRequest('GET', uri);

    final response = await request.send();
    ....
}

...


if (isRightGPS) {
	showSnackbar('교환위치 저장까지 성공했어요 🙌');
} else {
	showSnackbar('GPS 정보가 없어서 아쉬워요 😂');
}

BE 쪽에서의 처리 (안전장치 2)

   router.get('/', async (req, res) => {
      const { id_1, id_2, lat, lng } = req.query;
      ....
      ....

      if (lat !== '' && lng !== '') {
        nowlat = lat;
        nowlng = lng;
      } else {
        nowlat = '39.74023';
        nowlng = '134.33323';
      }

      result = await connections.connect(id_1, id_2, ids, nowlat, nowlng);
      ....
      ....
    
  });

FE와 동일하게, lat와 lng가 둘 다 정상적으로 들어온 경우에만 FE에서 넘겨준 인자를 사용하고 그 외에는 동해바다 좌표를 배정하도록 하였다.

이렇게 2가지 안전장치를 구비해놓으니, 명함을 수락하지 못하는 일은 해결할 수 있었다. 동일한 경우에 명함을 받고싶지 않아하는 경우는, 뒤로가기 버튼을 통해 진짜로 취소할지 확인받은 후에 정상적으로 실행하도록 이전에 해놨어서 특별히 추가할건 없었다.

iOS 빌드

기존에 TOOK 명함교환을 위해선 Nearby만 가능했으며, 구글 API인 탓인지 아이폰에서는 정상적으로 작동하지 않았다. 하지만 QR로 교환모드를 개발하면서 아이폰에서도 사용할 수 있는지 확인이 필요했다.

꾸준히 언급해왔듯이 우리의 핵심 기능은 Nearby를 활용한 명함 교환 기술인지라, 아무래도 그게 가능한 안드로이드를 일단 완성도를 최대한 높이는 방향으로 프로젝트가 진행되었다. 하지만 팀원 중 3명이 아이폰인데 iOS를 안하는게 너무 찜찜했고, 애초에 Flutter를 사용한거도 크로스 플랫폼을 겨냥하고 시작한 것이지 않았는가... 물론 팀 차원에서 iOS 빌드를 아예 해보지 않은 것은 아닌데, Nearby가 제대로 되지 않는 것을 인지한 후에는 거의 손을 놨었다.

하지만 이 프로젝트를 진행하며 항상 내가 직접 사용할 앱을 만들어보고 싶다는 생각에 열심히 해왔던지라, 개인적으로 내 핸드폰(아이폰12프로)에서도 꼭 써보고 싶었다. 하루 일찍 개발을 마감한(?) 김에, 직접 iOS 빌드에 시도했다.

처음에 몇 가지 문제점이 있었는데, 그래도 우여곡절 끝에 잘 끝냈다. 가장 주요한 원인은 맥북 자체에 설치한 것과 별개로 터미널을 Flutter 내의 iOS 폴더로 열어서 거기에도 pod install 을 해주어야 한다는 것이었다.

빌드에 성공한 후에, 우선 QR을 활용한 TOOK이 되는지 해보았다. 아주 잘 된다. 카메라 권한도 문제가 없었고 우려했던 가속도 센서도 문제없었다.

QR 교환기능 개발을 통해 우리의 잠재 사용자 폭이 훨씬 넓어졌다. 아이폰 사용자는 물론이고, 옛날 핸드폰이라 Nearby 기술을 활용할 수 없는 안드로이드 사용자까지 모두 QR을 통해서 동일하게 TOOK! 액션을 통해 명함을 교환할 수 있게 되었다. 이번 프로젝트를 진행하며 가장 뿌듯했던 순간이었다 :)

0개의 댓글