전체 글 (133) 썸네일형 리스트형 Chrome에서는 잘 되는데 iOS WebView에서 스크롤이 튀는 이유 같은 코드, 다른 결과이 앱은 React Native WebView 안에서 동작하는 웹앱입니다. 데스크톱 Chrome에서 테스트할 때는 괜찮아 보였던 스크롤 복원이, iOS 실기기에서는 간헐적으로 깜빡이거나 위치가 어긋나는 문제가 있었습니다.기존 코드의 주석이 이 상황을 잘 보여줍니다:// iOS WebView 스크롤 복원 전략:// - overflow 변경 없음 (iOS가 overflow 복원시 scrollTop 리셋하는 문제 방지)// - rAF 지연 없음 (iOS에게 자체 scroll 조정 틈을 주지 않음)// - getBoundingClientRect delta로 시각적 이동량을 정확히 보상// - flushSync → 즉시 scrollTop 보정이 한 JS 실행 블록에서 완료되어// 브라우저.. 하나의 웹앱, N개의 서버 — 빌드 없이 멀티 서버 환경에 대응한 이야기 시작은 하나의 회의실에서저희 팀은 공공기관의 민원 접수와 상황 보고를 위한 모바일 앱을 개발하고 있습니다. React 웹 SPA를 React Native WebView로 감싸, 웹과 앱 양쪽에서 하나의 코드베이스로 서비스하는 구조입니다.처음 이 프로젝트는 SI 외주 프로젝트였습니다. 특정 고객사 한 곳을 타겟으로 개발했고, 서버 주소도 하나로 고정되어 있었습니다. 그때는 아무 문제가 없었습니다.const BASE_URL = '';그런데 어느 날, 사내 회의에서 방향이 바뀌었습니다. "이 프로젝트를 내부로 가져와서, 여러 회사에 제공하자."한 곳만을 위해 만들던 서비스가, 갑자기 N개의 회사를 지원해야 하는 서비스가 된 것입니다. A기관은 https://a-agency.example.com, B기관은 ht.. VWorld 지도 위의 글자가 흐릿한 이유 문제를 발견한 순간서비스에는 데이터를 지도 위 마커로 표시하는 현황지도 기능이 있습니다. 사용자가 지도를 확대해서 특정 위치를 확인하는 것이 핵심 시나리오인데요.어느 날 QA 과정에서 한 가지 불편함을 발견했습니다."지도를 확대하면 건물 이름이랑 도로명이 뭉개져서 읽을 수가 없다."줌 레벨 14 정도까지는 괜찮았지만, 그 이상 확대하면 라벨이 점점 흐릿해졌습니다. 마커가 가리키는 위치가 정확히 어디인지, 주변에 어떤 건물이 있는지 파악하기 어려웠죠.원인은 명확했습니다. 래스터 타일이었습니다.래스터 타일의 한계기존에는 Cesium을 지도 엔진으로 사용하고 있었고, VWorld WMTS 서비스에서 PNG 래스터 타일을 받아와 렌더링하고 있었습니다.https://api.vworld.kr/req/wmts/1.0.. AI Agent 잘 다루기 출처 : https://www.youtube.com/watch?v=JzB_GI7SS6g 이제는 단순 구현 능력의 가치가 낮아지고 있습니다.대신, 설계 검증 디버깅 감각, 도구를 잘 다루는 능력이 중요해집니다.그런데 이런 설계와 검증이 주니어에게도 쉬울까…막상 Agent를 다루다 보면..AI에게 맡겼더니 알 수 없는 방향으로 코드가 완전히 달라짐꼬이면…어디서 잘못됐는지 몰라서 처음부터 다시 짜야한다.내가 시키긴 했는데…역시나 내 것이 아닌 느낌이 든다1. 느림보 설계먼저 생각하고, 나중에 맡기기AI에게 바로 던지면 생기는 일AI는 즉시 코드를 만들지만, 그게 내가 원하는 방향인지 알 수 없습니다.→ 설계 없이 시작하면 수정 비용이 눈덩이처럼 커진다.→ AI가 만든 구조를 따라가다 보면 내가 설계자가 아닌.. 채팅방 재전송 기능 구현: 두 런타임 사이의 실패 복구 들어가며채팅에서 메시지 전송은 실패할 수 있다. 네트워크가 끊기거나, 소켓이 닫혀 있거나, 서버가 일시적으로 응답하지 않을 수 있다. 사용자 입장에서 중요한 것은 "실패한 메시지를 다시 보낼 수 있는가"이다. 이 글에서는 React Native WebView 환경에서 텍스트와 미디어 메시지의 재전송 기능을 설계하고, 운영 중 발견한 구조적 문제를 개선한 과정을 정리한다.전체 구조재전송 시스템은 두 런타임에 걸쳐 있다.[React Native] ← 실패 메시지 영구 저장, 미디어 파일 보관, 재업로드[WebView Bridge] ← 메시지 타입 기반 양방향 통신[Web (React)] ← 실패 목록 UI 렌더링, 재전송 트리거, 텍스트 재전송핵심 설계 원칙은 RN의 AsyncStorage를 단일 원천.. 웹뷰 환경에서의 파일 처리 설계: Base64 전송에서 서버 임시 저장 방식으로 들어가며React Native WebView 기반 앱에서 파일 처리는 단순해 보이지만, 실제로는 두 런타임(네이티브 ↔ 웹) 사이의 브릿지 통신이라는 제약 아래서 동작한다. 특히 대용량 동영상 파일을 다루게 되면, "어디서 파일을 서버에 올릴 것인가"라는 설계 결정이 앱의 안정성을 좌우한다. 이 글에서는 기존 Base64 브릿지 전송 방식에서 tempFileId 기반 서버 임시 저장 방식으로 전환한 과정과, 그 과정에서 얻은 교훈을 정리한다.전체 구조파일 처리 시스템은 세 계층으로 나뉜다.[React Native] ← 파일 선택·압축·서버 업로드[WebView Bridge] ← tempFileId + 메타데이터 전달[Web App] ← tempFileId로 최종 전송 요청네이티브가 파일의 물.. 채팅 기능 구현 방식 — 연결·구독 설계 정리 들어가며실시간 채팅 기능을 구현할 때 가장 까다로운 부분은 메시지 전송 자체가 아니라, 연결과 구독의 생명주기 관리다. 언제 연결하고, 언제 끊고, 구독이 끊겼을 때 어떻게 복구할 것인가. 이 글에서는 STOMP over SockJS 기반의 채팅 기능을 설계하면서 적용한 연결-구독 구조와, 운영 중 발견한 문제를 개선한 과정을 정리한다.전체 구조채팅 시스템은 크게 세 계층으로 나뉜다.[소켓 클라이언트] ← 연결·구독·전송 (순수 함수)[라이프사이클 훅] ← 라우트 기반 연결/해제 타이밍 관리[화면 컴포넌트] ← 구독 콜백 등록, 메시지 렌더링소켓 클라이언트는 STOMP 연결과 구독을 담당하는 순수 유틸리티이고, 라이프사이클 훅이 React Router의 경로 변화에 따라 연결/해제 시점을 결정한다. .. 웹뷰와 웹소켓 핸들러 깔끔하게 관리한 방식 들어가며React Native WebView 기반의 하이브리드 앱을 개발하다 보면, 네이티브와 웹 사이의 메시지 통신이 점점 복잡해진다. 처음에는 화면마다 addEventListener('message')를 등록하는 것으로 충분했지만, 기능이 늘어나면서 동일한 보일러플레이트가 6곳 이상에 흩어지게 되었고, 일부는 cleanup이 누락되어 리스너가 누적되는 버그까지 발생했다.이 글에서는 흩어져 있던 메시지 핸들러를 정리한 과정을 정리한다.기존 구조의 문제점1. 반복되는 보일러플레이트React Native WebView에서는 Android와 iOS의 메시지 수신 방식이 다르다. Android는 document에, iOS는 window에 이벤트가 발생하기 때문에 양쪽 모두에 리스너를 등록해야 한다.const .. 이전 1 2 3 4 ··· 17 다음