수영장(Sooyoung Archive)
홈개발일지이번캠App소개
전체보기
프로젝트
기술 & 개발

© 2026 수영장 (Sooyoung Archive). All rights reserved.

개인정보처리방침연락처
개발일지 목록
프로젝트

이번캠 운영기 2: 로그인부터 뒤로가기까지, 사용자의 흐름을 지키기

2026년 10월 29일약 15분 소요0회 조회

앱을 만들면서 가장 자주 확인한 것은 기능이 되는지였다. 좋아요가 저장되는지, 사진이 올라가는지, 로그인에 성공하는지 같은 것들이다.

그런데 다른 사람이 앱을 사용하기 시작하니 조금 다른 이야기가 들렸다.

로그인이 필요하면 알림만 보여주지 말고 로그인 화면으로 보내주세요. 로그인하고 나면 원래 보던 화면으로 돌아오고요.

기능이 없는 문제는 아니었다. 로그인도 있었고, 좋아요도 있었다. 다만 그 사이에서 사용자가 하려던 일이 끊기고 있었다.

지난 이번캠 운영기에서는 커뮤니티 분리와 공통 페이지 이동 비용을 다뤘다. 이후에는 큰 기능을 더하기보다 이미 있는 흐름을 다시 살폈다. 이번 글은 10월 20일부터 27일까지 반영한 로그인 복귀, 반응 처리, 미디어 선택·복구와 피드 상태 유지에 관한 기록이다.

이번캠은 Next.js·Supabase 기반 웹을 Capacitor 앱 셸에서 로드한다. 그래서 같은 화면이어도 일반 브라우저와 앱의 인증·파일 선택 조건은 구분해서 봐야 했다.

1. 로그인에 성공하는 것과 원래 하던 일을 이어가는 것은 달랐다

비로그인 상태에서 좋아요를 누르면 로그인이 필요하다는 안내가 나왔다. 개발하는 입장에서는 이유를 알려주고 있으니 충분하다고 생각하기 쉽다. 하지만 사용자는 하트를 눌렀는데 아무 일도 일어나지 않는다고 느낄 수 있었다. 화면 위쪽에 잠깐 나타나는 알림을 매번 찾아보리라는 보장도 없었다.

그래서 인증이 필요한 동작은 로그인으로 이어지고, 로그인을 마치면 원래 맥락으로 돌아오도록 흐름을 정리했다.

여기서 맥락은 페이지 주소만 뜻하지 않는다. 피드 아래쪽에서 보던 글이 있었다면 로그인 뒤에도 그 글을 찾을 수 있어야 한다. URL과 함께 스크롤 위치, 가능하면 게시물 기준 위치도 짧게 보관하도록 했다.

현재 구현은 로그인 복귀 정보를 sessionStorage에 저장하고, 로그인 후 한 번 읽으면 제거한다. 보관 시간은 15분으로 제한했다. 목적지가 안전한 내부 경로인지, 현재 경로와 맞는지, 계정 조건이 맞는지도 확인한다. 무한 스크롤에서 보던 글이 아직 목록에 없으면 무한히 위치 복원을 시도하는 대신 해당 글의 상세 화면으로 돌아가는 대체 경로를 둔다.

또 중요한 구분이 있었다. 로그인 화면에서 돌아오는 경험을 고치는 것과 로그인이 자주 풀리는 원인을 해결하는 것은 같은 일이 아니다.

이번에는 Supabase 토큰 갱신 요청의 성공·HTTP 오류·네트워크 오류·중단 결과와 앱 실행·복귀 시 세션 확인 결과를 구분해서 기록하도록 보강했다. 토큰이나 세션 본문을 저장하는 방식은 아니다. 허용한 상태, 시간과 오류 분류만 남기고 전송량도 제한한다.

SIGNED_OUT 이벤트 하나만 보고 토큰이 만료됐다고 결론 내리지 않도록 한 것도 같은 이유다. 관찰된 결과와 추정한 원인을 나누어야 다음 오류를 조사할 수 있다.

이번 변경을 “로그인 풀림을 전부 해결했다”라고 소개하지는 않는다. 먼저 다시 로그인해야 하는 상황에서 사용자가 덜 막히게 만들고, 반복되는 인증 문제는 더 구체적으로 확인할 수 있게 한 작업이다.

2. 좋아요는 숫자뿐 아니라 반응과 사람을 보여주는 기능이었다

좋아요에서 받은 피드백은 두 가지였다. 눌렀을 때 반응이 매끄럽지 않다는 것, 그리고 누가 눌렀는지 보고 싶다는 것이었다.

이전 운영기에서 이미 낙관적 업데이트를 다뤘지만, 이번에는 연속 입력과 실패 복구를 더 살폈다. 화면을 먼저 바꾼다는 원칙만으로는 충분하지 않았다. 사용자가 켰다가 바로 끄는 사이에 오래된 응답이 도착하면, 화면이 다시 이전 상태로 돌아갈 수 있기 때문이다.

현재 좋아요 액션은 단순히 “반대로 바꾸기”보다 사용자가 최종적으로 원하는 상태를 전달하는 setLike(postId, shouldLike) 형태다. 화면의 의도와 서버가 확인한 상태를 구분하고 저장 흐름을 맞추는 쪽으로 보완했다. 댓글과 팔로우도 빠른 입력, 실패와 인증 필요 상태를 함께 점검했다.

여기에 좋아요를 누른 사람 목록과 대표 프로필 요약을 추가했다. 숫자만 표시하는 대신 누군가 반응했다는 것을 피드 안에서 확인하고, 필요하면 목록을 열어볼 수 있다.

목록은 처음부터 모두 내려받지 않는다. 사용자가 열었을 때 읽고, 한 번에 20개씩 커서로 이어서 조회한다. 공개된 글인지 확인하고, 차단한 사용자와 숨김·비공개 조건도 고려한다. 피드 요약용 프로필과 전체 목록 조회를 분리한 이유는 작은 UI 하나 때문에 모든 카드의 데이터를 무겁게 만들고 싶지 않았기 때문이다.

“인스타처럼 보이면 좋겠다”는 요청을 그대로 모양만 따라가는 작업으로 끝내지 않으려 했다. 작은 표시 하나를 추가해도 조회 시점, 공개 범위와 실패 상태를 같이 정해야 했다.

3. 사진 다섯 장 중 한 장이 실패하면 어떻게 할 것인가

사진과 영상은 이번캠에서 가장 기본적인 입력이다. 글을 쓰기 전에 파일을 고르는 단계에서 막히면 이후 기능은 써볼 기회도 없다.

실제로 iPhone에서 사진 미리보기가 나오지 않거나, 사진과 영상을 함께 선택하는 흐름이 기대와 다르다는 피드백이 있었다. 파일을 선택하는 것, 웹에서 읽을 수 있는 파일을 얻는 것, 미리보기를 만드는 것과 업로드는 각각 다른 단계였다.

이번에는 iOS 영상 선택·촬영에서 파일 입력이 반환하는 File 객체를 기존 준비·업로드 흐름에 연결했다. 이 경로에서는 기기 내부의 file://·capacitor:// 주소를 웹에서 다시 읽는 방식에 의존하지 않는다. Android의 네이티브 선택 경로와는 구분해서 유지했다.

여기에는 대가도 있다. iOS의 이 선택 경로에는 네이티브 원본 경로가 없으므로, 그 경로를 필요로 하는 자동 영상 압축은 건너뛴다. 영상 길이와 용량 제한은 여전히 검사한다. 파일 읽기를 바꿨다고 큰 영상까지 모두 처리할 수 있게 된 것은 아니다.

미디어 준비 과정도 항목별로 실패를 다루도록 정리했다.

  • 준비된 파일은 유지하고, 중복·제한 초과·실패한 파일 수를 구분한다.
  • 한 항목의 실패 때문에 이미 준비한 다른 항목을 모두 버리지 않는다.
  • 영상 포스터 생성이 실패해도 영상 자체를 유지할 수 있는 경로를 둔다.
  • 화면에 붙이지 못한 임시 미리보기 주소는 해제한다.

업로드를 재시도할 때 이미 끝난 작업을 재사용하는 흐름, 작성 내용의 임시저장과 복구도 함께 살폈다. 사용자가 “실패했다”는 문구만 보는 것과, 어떤 항목이 남아 있고 무엇을 다시 해야 하는지 아는 것은 다른 경험이다.

다만 앱을 닫거나 기기에서 원본이 사라진 경우까지 모든 미디어가 복구된다는 뜻은 아니다. 특히 실제 iPhone에서의 선택·촬영·재생 검증과 다양한 원본 형식 확인은 계속 필요한 영역이다.

4. 없는 캠핑장을 요청하려는데 정보를 다시 찾아 적어야 했다

캠핑장 목록에 원하는 장소가 없으면 추가 요청을 보낼 수 있다. 그런데 요청 화면을 여는 것만으로 입력 부담이 줄어들지는 않았다. 사용자는 이름을 검색하고, 주소를 확인하고, 전화번호를 다시 가져와야 했다. 관리자도 등록 과정에서 비슷한 일을 반복할 수 있었다.

그래서 요청과 관리자 등록 흐름에 카카오맵 장소 검색을 연결했다. 검색 결과를 선택하면 이름, 주소, 전화번호와 좌표 같은 기본 정보를 폼에 가져오는 방식이다.

검색 결과는 그대로 신뢰하는 문자열로 취급하지 않았다. 장소 ID와 링크 형식, 이름·주소 길이, 좌표 범위를 검사한다. 검색을 연달아 실행했을 때 이전 결과가 새 결과를 덮지 않도록 요청 순서를 구분하고, 시간이 오래 걸리면 직접 입력으로 이어질 수 있게 안내한다.

이 기능은 캠핑장 정보 전체를 자동 완성하거나 외부 정보를 검증 없이 등록하는 기능이 아니다. 시설, 가격과 실제 운영 여부는 별도로 확인해야 하고 관리자 검토도 남는다. 목적은 검토를 없애는 것이 아니라 같은 기본 정보를 여러 번 옮겨 적는 일을 줄이는 데 있었다.

5. 빨리 돌아왔는데 보던 사진이 바뀌면, 제대로 돌아온 걸까

가장 인상적이었던 보완은 뒤로가기였다.

피드에서 사진을 넘기고 캠핑장이나 작성자 화면을 구경한 뒤 돌아오면, 스크롤 위치는 비슷해도 사진 순서가 처음으로 돌아가는 경우가 있었다. 무한 스크롤로 읽은 글이 사라져 다시 불러와야 하는 경우도 있었다.

10월 27일 운영 브라우저 점검에서는 첫 게시물의 세 번째 사진을 고른 뒤 캠핑장에 다녀오자 가로 사진 위치가 초기화되는 현상을 기록했다. 글 18개를 불러온 뒤 작성자 화면에 다녀오면 처음 여섯 개만 남는 흐름도 확인했다. 이 기록은 상태 유실을 확인한 것이지 네트워크 속도를 측정한 자료는 아니다.

단순히 스크롤 값 하나를 저장해서는 부족했다. 최소한 다음 정보가 함께 있어야 했다.

보존할 정보필요한 이유
이미 읽은 목록과 다음 커서아래쪽 글을 다시 불러오지 않고 이어보기 위해
게시물별 사진 순서세 번째 사진을 보다가 첫 번째로 돌아가지 않도록
게시물 기준 위치와 스크롤 값화면 높이가 달라져도 보던 글을 기준으로 맞추기 위해
계정·검색 조건·피드 범위다른 화면의 상태를 잘못 복원하지 않도록

현재는 이 정보를 짧게 유지하는 메모리 스냅샷으로 관리한다. 유효 시간은 5분, 최대 8개 화면과 스냅샷당 120개 글로 범위를 제한했다. 피드 본문을 브라우저 영구 저장소에 쌓아두는 방식은 아니다.

복원 조건도 중요했다. 새로 피드에 들어오는 상황까지 이전 화면으로 되돌리면 사용자는 새 글을 보려다가 과거 목록으로 이동하게 된다. 같은 조건의 히스토리 복귀인지 확인하고, 계정이나 콘텐츠 관계가 바뀌면 스냅샷을 비운다. 서버가 준 첫 페이지의 게시물 구성이 달라졌을 때도 예전 목록을 무조건 붙이지 않는다.

위치를 맞추는 도중 사용자가 직접 스크롤하거나 화면을 누르면 복원을 멈춘다. 자동 복원이 사용자의 새 행동과 싸우면 또 다른 불편이 되기 때문이다. 댓글 창을 다시 열거나 영상을 자동으로 재생하는 상태까지 복원하지는 않는다.

여기서 느낀 것은 이동 성능과 상태 유지는 함께 봐야 한다는 것이다. 돌아오는 요청이 빨라져도 방금 보던 글과 사진을 다시 찾아야 한다면 사용자는 여전히 앱이 매끄럽지 않다고 느낀다.

메모리 기반인 만큼 문서가 완전히 새로 로드되거나 앱이 종료된 뒤에도 같은 상태가 남는다고 보장하지는 않는다. 웹의 뒤로가기, 화면 안의 뒤로가기와 앱의 뒤로가기를 같은 것으로 단정하지 않고 확인해야 할 이유도 여기에 있다.

6. 오류를 모으는 것에서, 다음에 확인할 단서를 남기는 쪽으로

이번 작업에서는 새 기능만큼 오류를 조사할 수 있는 정보도 중요했다. 로그인 문제를 사용자 제보만으로 다시 추측하지 않으려면 어떤 단계에서 실패했는지 구분할 수 있어야 했다.

인증 진단에는 작업 결과, 플랫폼과 릴리스 같은 제한된 정보를 남긴다. 미디어 처리도 선택과 준비 단계의 맥락을 구분한다. 인증 토큰, 파일 내용이나 원본 오류 메시지를 무조건 쌓는 방식은 피했다.

이 기록이 모든 로그인 시도를 대표하지는 않는다. 수집 제한, 네트워크 단절이나 차단으로 이벤트가 빠질 수 있으므로 기록된 건수만으로 전체 장애율을 계산할 수도 없다. Sentry에 이벤트가 보인다는 것과 원인이 해결됐다는 것도 구분해야 한다.

회귀 테스트에는 로그인 복귀, 세션 처리, 좋아요 목록, 미디어 복구와 피드 스냅샷의 경계 조건을 다루는 파일들이 추가됐다. 이번 글을 작성하면서 전체 테스트나 실제 기기 시나리오를 새로 실행한 것은 아니다. 따라서 테스트 파일이 있다는 사실을 모든 기기의 문제가 해결됐다는 근거로 쓰지는 않는다.

7. 만들기만 하던 앱을 설명하기 시작했다

이후에는 앱을 알리는 일도 조금 시작했다. ibeon.archive 계정을 만들고 인스타그램과 스레드에 첫 소개 영상을 올렸다.

여기서도 앱을 어떤 말로 소개할지 다시 생각하게 됐다. 피드가 있으니 캠핑 사진을 보는 서비스이기도 하지만, 내가 어디에 다녀왔고 어떤 시간을 보냈는지 남기는 도구이기도 하다.

그래서 첫 영상은 기능을 전부 나열하는 대신 **“캠핑의 순간을 모으다”**라는 이야기로 묶었다. 방문 지도, 저장과 플랜은 별도의 소재로 나눠 소개하려 한다. 아직 홍보 성과나 설치 증가를 평가할 단계는 아니다. 우선 실제 사용 흐름을 보여주고 의견을 듣기 시작한 것이다.

개발에서도 홍보에서도 같은 질문이 남았다. 기능이 얼마나 많은가보다, 사용자가 이 앱을 왜 다시 열고 싶을까.

최근의 보완은 대부분 새로운 탭을 만드는 일이 아니었다. 로그인하고 돌아오기, 방금 누른 반응을 이해하기, 준비한 사진을 잃지 않기, 보던 곳으로 돌아오기 같은 일들이었다.

다음에도 새 기능을 고민하겠지만, 그 전에 사용자가 이미 시작한 일을 끝낼 수 있는지부터 확인하려 한다.


이번캠은 웹, App Store, Google Play에서 사용할 수 있다. 서비스 흐름은 이번캠 프로젝트 소개에 정리했다.

클릭할 때마다 작가에게 따뜻한 응원이 전달됩니다 ❤️

이 글이 유익하셨나요?
동료 개발자들과 경험과 노하우를 공유해 보세요.
이전 글프로젝트
이번캠 운영기: 사용자 피드백에서 커뮤니티 분리와 이동 성능 개선까지

함께 읽으면 좋은 다른 개발일지

'프로젝트' 및 추천 아카이브 글 모음

이번캠 운영기: 사용자 피드백에서 커뮤니티 분리와 이동 성능 개선까지
프로젝트
이번캠 운영기: 사용자 피드백에서 커뮤니티 분리와 이동 성능 개선까지
출시한 캠핑 서비스를 운영하며 로그인·반응·업로드 흐름을 보완하고, 방문 기록과 커뮤니티를 분리한 과정. 서울 리전, 요청 단위 캐시와 응답 경합을 다루며 측정 조건과 모바일 검증의 한계까지 정리했다.
2026. 10. 12.

댓글

댓글 개인정보 안내
목차
1. 로그인에 성공하는 것과 원래 하던 일을 이어가는 것은 달랐다2. 좋아요는 숫자뿐 아니라 반응과 사람을 보여주는 기능이었다3. 사진 다섯 장 중 한 장이 실패하면 어떻게 할 것인가4. 없는 캠핑장을 요청하려는데 정보를 다시 찾아 적어야 했다5. 빨리 돌아왔는데 보던 사진이 바뀌면, 제대로 돌아온 걸까6. 오류를 모으는 것에서, 다음에 확인할 단서를 남기는 쪽으로7. 만들기만 하던 앱을 설명하기 시작했다
0회
캠핑인스타 만들기 5편: '이번캠(MyCamp)' 리브랜딩과 Capacitor로 Apple App Store 심사 통과한 이야기
프로젝트
캠핑인스타 만들기 5편: '이번캠(MyCamp)' 리브랜딩과 Capacitor로 Apple App Store 심사 통과한 이야기
캠핑인스타를 '이번캠(MyCamp)'으로 리브랜딩하고, Capacitor를 활용해 Next.js 웹 서비스를 Apple App Store(iOS)에 공식 출시하며 겪은 심사 통과와 트러블슈팅 기록.
2026. 8. 26.15회
그림톡 만들기 3편: '한 번 답하는 앱'에서 '계속 대화하는 친구'로 바꾸기
프로젝트
그림톡 만들기 3편: '한 번 답하는 앱'에서 '계속 대화하는 친구'로 바꾸기
그림톡에서 단발성 응답을 넘어 대화가 계속 이어지는 소셜 인터랙션과 프롬프트 엔지니어링 과정을 정리한 개발 일지.
2026. 3. 30.68회