2023-04-23: 개인 프로젝트 도전기 (14주차)
목표 정산
프리릴리즈요? 그런 거 없었다..
대신에 릴리즈가 되면 본격적으로 배치하려고 했던 매장에 사장님께서 그쪽에 바로 배치하겠다고 하셔서 프리 릴리즈가 아닌 정식 릴리즈가 되어버렸다.
다만, 그러기 위한 계정 생성이 많이 늦어져서 릴리즈가 또 늦어진 것은.. 다른 이야기다..
이번 주에 진행한 내용은 아래와 같다.
임시 QR 코드 발급창 추가구글 애널리틱스 배치- 이미지 업로드 기능 구현
추가 QA 진행- 프리 릴리즈 진행
이번에 QR 코드 발급창을 만들면서 다운로드 기능을 구현해보기도 했는데, 업로드는 해본 적 있어도 다운로드를 만들어본 적은 없었기 때문에 되ㄴ게 신선한 경험이었다.
그리고 슬슬 기능을 이용하면서 얼마나 많은 사람들이 이 기능을 이용하는지도 파악하고 싶어서 구글 애널리틱스를 배치해봤다.
QR code API를 이용해 QR코드를 발급해보자
고객들이 대기 등록을 진행하기 위해서는 QR코드를 사진으로 찍어 들어간 페이지에서 진행하도록 해야 했다.
포스터로 따로 만들어서 발급해주는 식으로 진행하려고 했지만, 당장 대기 등록이 필요한 경우를 고려하여 QR Code 관련 이미지를 저장하거나 보여줄 수 있으면 좋겠다 싶은 생각에 임시로라도 관련 사항을 적용할 수 있도록 작업하고자 했다.
그러기 위해서는 QR 코드 이미지를 발급받을 수 있는 API가 필요했는데 어떤 API가 있을까 하다가, 아래와 같은 API 레퍼런스 사이트를 찾게 됐다.
사용법은 아래와 같다.
https://api.qrserver.com/v1/create-qr-code/?size=(width)x(height)&data=(연결할 데이터)
위의 링크를 통해서 발급이 가능한 점을 참고하여, QR Code 이미지를 드러낼 모달창에 아래와 같이 코드를 작성했다.
<Modal isOpen={isOpen} onClose={onClose}> <ModalOverlay /> <ModalContent wordBreak="keep-all" padding="1.5rem 0" margin="2rem 1rem"> <ModalHeader fontSize="1.25rem" fontWeight="semibold" padding="0 1rem" textAlign="center" margin="0.5rem 0" > 임시 QR 코드 </ModalHeader> <ModalBody display="flex" flexDirection="column" gap="1rem"> <Image src={`https://api.qrserver.com/v1/create-qr-code/?data=https://waitsecond.vercel.app/store/${loginStateCheck()}&size=250x250`} /> 코드 인쇄 등을 위해 이미지를 저장하고 싶으시면 아래를 클릭해주세요. </ModalBody> <ModalFooter display="flex" flexDirection="column" width="100%" gap="1rem" > <Button type="button" background="mainBlue" color="#FFFFFF" fontWeight="medium" fontSize="1.25rem" padding="0.5rem 0" width="100%" borderRadius="0.25rem" height="3rem" onClick={downloadQRCodeImage} > 코드 이미지 다운로드 </Button> <Button type="button" background="accentGray" color="#FFFFFF" fontWeight="medium" fontSize="1.25rem" padding="0.5rem auto" width="100%" borderRadius="0.25rem" height="3rem" onClick={onClose} > 창 닫기 </Button> </ModalFooter> </ModalContent> </Modal>
발급된 QR 코드를 버튼을 통해 다운로드 받게 해볼까?
QR Code 이미지가 나타나는 것은 좋지만, 경우에 따라서는 QR Code를 다운로드 받고 싶은 경우도 있지 않을까?
그런 생각을 하니, QR Code 이미지를 다운로드할 방법도 고려해야겠다고 생각했다.
예전에 업로드를 구현한 적은 있지만, 다운로드를 구현해본 적은 없어서 조금 신기한 느낌이었다.
구글링으로 찾아본 결과, 다운로드를 구현하는 방법은 blob 객체에서 나온 데이터를 통해서 가상의 a태그를 만들고 그걸 클릭시킨 뒤, 해당 태그를 삭제하는 식으로 진행되는 듯 했다.
API를 통해서 데이터를 가져오도록 통신한 다음에, 받아온 데이터를 blob 객체로 받아온 뒤 이를 가지고 객체의 URL를 만들어내서 다운로드를 만들어내는 거였다.
구현된 코드는 아래와 같다.
const downloadQRCodeImage = (e: React.MouseEvent) => { e.preventDefault(); // axios를 설치하지 않았으므로, fetch로 가볍게 처리 // 지금 보니 async function으로 처리할까 싶기도 하다. const linkURL = `https://api.qrserver.com/v1/create-qr-code/?data=https://waitsecond.vercel.app/store/${loginStateCheck()}&size=800x800`; fetch(linkURL, { method: "GET", }) // 위에서 fetch 통신을 통해서 응답받은 데이터를 blob 객체로 받아오도록 함. .then((response) => response.blob()) .then((blob) => { // 받아온 blob 객체를 새로운 Blob 인스턴스로 배정 const blobData = new Blob([blob]); // Blob 인스턴스로부터 Object URL 생성 const fileObjectURL = window.URL.createObjectURL(blobData); // 다운로드를 받을 anchor 요소를 생성 const downloadAnchor = document.createElement("a"); // 다운로드 링크는 위에서 만든 Object URL을 하이퍼링크로 배정 downloadAnchor.href = fileObjectURL; downloadAnchor.style.display = "none"; // 다운로드 파일명을 QRCode.png로 적용 downloadAnchor.download = "QRCode.png"; // 다운로드 후 삭제 적용 downloadAnchor.click(); downloadAnchor.remove(); // revokeObjectURL을 통해 생성한 객체 URL을 해체해 지우도록 한다. window.URL.revokeObjectURL(fileObjectURL); }); };
이런식으로 구현해보고 테스트를 해보니 잘 작동되는 것을 확인했다.

가상의 anchor 요소를 만들어서 숨기고, 그걸 함수를 이용해 클릭하고 지우도록 만드는 게 왜인지 웃기기도 하면서 이런 방식으로도 다운로드 구조가 만들어지는구나 싶어서 재밌는 경험이었다.
다음에 시간이 나면 다른 다운로드 방식이 있는지도 좀 조사해보고 싶다.
오랜만에 해보는 구글 애널리틱스 적용
과거에 프로젝트를 진행했었을 때 구글 애널리틱스를 진행하긴 했지만, 오랜만에 배치를 해보려니까 생각이 나질 않았다.
배치하기 위해서 어떻게 하면 되는지, 추후에도 분명 쓸 일이 있을 거기에 관련 내용을 이 참에 기록해둬보고자 한다.
구글 애널리틱스를 사용하려면, 우선 콘솔에 들어가야한다.
WaitSecond에서는 Firebase를 이용하고 있기 때문에, Firebase 콘솔에서 확인할 수 있지만 통계 모듈을 배치하려면 구글 애널리틱스 콘솔에서 직접 봐야한다.
설정 → 속성 → 데이터 스트림에 보면 등록되어있는 데이터 스트림을 볼 수있다.

데이터 스트림을 누르면 모달이 출력되는데, 메뉴 중 태그 안내 보기를 눌러보자.

팝업이 하나가 더 출력될텐데, 저 중에 ‘직접 설치’라는 항목을 누르면 수동으로 구글 애널리틱스 태그를 배치할 수 있는 코드가 출력된다.

복사하기 버튼을 누른 후, 안내 내용이 나온 대로
요소에 배치해야하므로, 프로젝트 내 public 폴더의 index.html 파일에 해당 요소를 배치해주고 빌드 및 배포해주면 본격적으로 분석을 진행할 수 있다.
내가 알고 있는 방법은 여기까지였고, 여기서 더 활용할 방법을 잘 알진 못했는데.. 작업한 과정을 트위터를 통해 보시던 숲속캠퍼(@masan_aje) 님께서 여러 조언을 해주셨다.
요약하자면, GA의 기능 중에서는 그냥 head 요소에 태그를 배치하는 것으로 끝나는 게 아니라, 특정 이벤트에 코드를 배치해 어떤 이벤트들이 일어났는지를 이것 또한 통계로 낼 수 있다고 알려주셨다.
GA에서 통계내는 방법이 단순히 태그만 배치하면 된다고 생각했는데, 자체에서도 다양한 기능들이 존재하고 이걸 어떻게 활용하느냐에 따라서 방대한 통계의 활용을 구현해낼 수 있다는 점이 되게 신기했다.
당장은 적용할 스펙은 아니지만, 추후에 작업을 적용해보고 싶어 우선은 github project 칸반에 하나 추가해뒀다. 나중에 작업하게 된다면 관련 이야기를 또 회고로 올리도록 하겠다.
다음주에 할 일들
사장님하고 계속해서 이야기를 진행하고 있는데, 일단은 다음주에 진짜 배치하기로 이야기를 마치면서 남은 기능들을 마저 구현하고자 한다.
- 이미지 업로드 기능 구현
- 릴리즈 진행 및 매장 배치
- README 수정
- QA 진행 및 버그 수정
이제는 진짜 릴리즈, 런칭을 하고 싶다. 간절한 마음으로 다음주의 작업에 최대한 올인해보자.