@devdzipup/partners
v0.1.13
Published
React Native SDK for Zipup OpenAPI - Native module for integrating Zipup services into iOS and Android applications
Readme
@devdzipup/partners 개발 문서
본 문서는 Zipup OpenAPI React Native 네이티브 브리지 SDK인 @devdzipup/partners의 구조, 설치 방법, API, 라이프사이클, 네이티브 연동 방식을 개발자 관점에서 이해하기 쉽게 정리한 문서입니다.
빠른 사용법 (Quick Start)
SDK를 앱에 붙여서 최소한으로 동작시키는 순서는 다음과 같습니다.
- 설치:
npm install @devdzipup/partners후 iOS는pod install - 초기화: 앱 실행 후 한 번
init(userKey, userPhone, proxyUrl)호출 - 이벤트 구독:
addListener로onOpen,ready,onClose수신 - 화면 열기: 버튼 등에서
open()호출 - 정리: 화면/컴포넌트를 벗어날 때
removeListener(구독객체)호출
자세한 사용 흐름과 주의사항은 아래 Part 4 사용 시나리오와 각 API 설명을 참고하세요.
Part 1. 개요
1.1 라이브러리 소개
@devdzipup/partners는 Zipup OpenAPI를 React Native(iOS/Android) 환경에서 사용할 수 있도록 감싼 네이티브 브리지 SDK입니다.
- npm 패키지명:
@devdzipup/partners - 사용자 문서:
README.md - 개발 문서: 본 문서 시리즈 (
mark.md기준)
1.2 주요 특징
| 항목 | 설명 |
| ------------- | ---------------------------------------- |
| 크로스 플랫폼 | iOS / Android 동시 지원 |
| TypeScript | 타입 정의 포함 (.d.ts) |
| TurboModule | React Native TurboModule 기반 |
| 이벤트 기반 | onOpen, onClose, ready 이벤트 수신 |
| 네이티브 래핑 | Android AAR / iOS XCFramework 래핑 |
Part 2. 설치 및 개발 환경
2.1 라이브러리 사용자 설치
npm install @devdzipup/partners
# or
yarn add @devdzipup/partners- iOS:
cd ios && pod install - Android: Gradle Sync 자동 처리 (AAR 포함)
사용 시 참고: userKey, userPhone, proxyUrl은 Zipup 파트너/백엔드에서 발급·제공하는 값입니다. 앱에서 하드코딩하지 말고 환경 변수나 설정 API로 불러오는 것을 권장합니다.
2.2 라이브러리 개발 환경
SDK 자체를 수정·배포하는 개발자를 위한 환경입니다.
2.2.1 요구 사항
| 항목 | 버전 | | ------------ | --------- | | React Native | >= 0.83.0 | | iOS | >= 13.0 | | Android | API 21+ | | Node.js | LTS 권장 | | Yarn / npm | 최신 안정 |
2.2.2 사용 도구
| 목적 | 도구 | | ------ | ------------------------ | | 빌드 | react-native-builder-bob | | 린트 | eslint, prettier | | 테스트 | jest | | 릴리스 | release-it | | Git 훅 | lefthook, commitlint |
2.2.3 초기 실행
yarn
# 예제 앱 실행
yarn examplePart 3. 프로젝트 구조
3.1 디렉터리 구조
zipup-sdk-rn/
├── src/ # JS/TS 공개 API 및 브리지
├── android/ # Android 네이티브 모듈
├── ios/ # iOS 네이티브 모듈
├── example/ # 예제 앱
├── lib/ # 빌드 산출물
├── docs/ # 개발 문서
└── README.md3.2 src/
| 파일 | 설명 | | ------------------------ | --------------------- | | index.tsx | 공개 API 진입점 | | NativeZipupOpenapiSdk.ts | TurboModule 스펙 정의 |
Part 4. 공개 API 레퍼런스
import {
init,
open,
close,
addListener,
removeListener,
} from '@devdzipup/partners';4.1 init
SDK를 사용자 정보로 초기화합니다.
init(userKey: string, userPhone: string, proxyUrl: string): string;- 언제 호출할까: 앱이 Zipup 화면을 띄우기 전에 한 번만 호출하면 됩니다. 보통 앱 기동 시(예: 루트 컴포넌트 마운트 시) 또는 로그인 직후에 호출합니다.
- 반환값: 성공 시
"init success"등 성공 메시지, 실패 시"error: ..."문자열. - 실패 시에는
open()을 호출하지 말고, 에러 메시지를 로그/모니터링하고 사용자에게 안내하는 것이 좋습니다.
사용 예 (에러 처리 포함):
const result = init(USER_KEY, userPhone, PROXY_URL);
if (result.startsWith('error:')) {
console.error('Zipup init 실패:', result);
return;
}
// 이후 open() 호출 가능4.2 open
Zipup SDK 화면을 엽니다.
open(): string;- 언제 호출할까: "Zipup 열기" 버튼 클릭, 특정 플로우 진입 시 등 사용자가 SDK 화면을 보려는 시점에 호출합니다.
- 주의:
init()을 먼저 호출하지 않으면 동작이 보장되지 않습니다.open()직후 10초 안에ready이벤트가 오지 않으면 SDK가 자동으로close()됩니다.
사용 예:
const result = open();
if (result.startsWith('error:')) {
showToast('Zipup을 열 수 없습니다.');
}4.3 close
SDK 화면을 닫습니다.
close(): string;- 언제 호출할까: 사용자가 "닫기"를 눌렀을 때, 또는
onClose이벤트를 받았을 때 정리 차원에서 호출할 수 있습니다. 타임아웃 시 SDK 내부에서 자동 호출되므로, 수동으로는 명시적으로 화면을 닫고 싶을 때만 호출하면 됩니다. - 콜백 안에서 호출 시: 이벤트 리스너 콜백 안에서 곧바로
close()를 호출하면 같은 호출 스택에서 네이티브가 닫혀 문제가 될 수 있으므로, 필요하면setTimeout(() => close(), 0)처럼 한 틱 미뤄서 호출하는 것을 권장합니다.
4.4 addListener / removeListener
이벤트를 구독·해제할 때 사용합니다.
const sub = addListener((event) => {
console.log(event.event, event.data);
});
removeListener(sub);type ZipupEventData = {
event: 'onOpen' | 'onClose' | 'ready';
data?: Record<string, any>;
};- 언제 addListener할까: Zipup 화면을 한 번이라도 열 계획이 있는 컴포넌트/화면에서, 해당 컴포넌트가 마운트될 때
addListener를 호출합니다.open()보다 먼저 구독해 두는 것이 안전합니다. - 언제 removeListener할까: 해당 컴포넌트가 언마운트될 때 반드시
removeListener(sub)를 호출합니다. 그렇지 않으면 리스너가 남아 메모리 누수나 중복 호출이 발생할 수 있습니다.
사용 예 (React 훅/컴포넌트):
useEffect(() => {
const sub = addListener((e) => {
if (e.event === 'onOpen' && e.data?.url) {
Linking.openURL(e.data.url);
}
if (e.event === 'onClose') {
// 닫힘 처리 (필요 시 close() 호출은 setTimeout으로)
}
});
return () => removeListener(sub);
}, []);4.5 사용 시나리오 요약 (권장 호출 순서)
| 순서 | 작업 | 설명 |
| ---- | ----------------------- | ------------------------------------------------------------------- |
| 1 | init(...) | 앱/화면 진입 시 한 번. 실패 시 open 호출 금지. |
| 2 | addListener(callback) | open 전에 구독. onOpen 시 URL 있으면 Linking.openURL 등 처리. |
| 3 | open() | 사용자 액션(버튼 등)에서 호출. |
| 4 | (선택) close() | 사용자가 닫기 시 등 필요 시. 타임아웃 시 자동 호출됨. |
| 5 | removeListener(sub) | 컴포넌트 언마운트 시 반드시 호출. |
한 화면에서 처음부터 끝까지 쓰는 예시는 아래와 같습니다.
import { useEffect, useState } from 'react';
import { Button, Text, Alert, Linking } from 'react-native';
import { init, open, addListener, removeListener } from '@devdzipup/partners';
// 예: Zipup을 여는 화면 컴포넌트
function ZipupScreen() {
const [ready, setReady] = useState(false);
useEffect(() => {
// USER_KEY, userPhone, PROXY_URL: 환경변수·설정·props 등에서 주입
const r = init(USER_KEY, userPhone, PROXY_URL);
if (r.startsWith('error:')) return;
const sub = addListener((e) => {
if (e.event === 'ready') setReady(true);
if (e.event === 'onOpen' && e.data?.url) Linking.openURL(e.data.url);
if (e.event === 'onClose') setReady(false);
});
return () => removeListener(sub);
}, []);
const handleOpen = () => {
const r = open();
if (r.startsWith('error:')) Alert.alert('오류', 'Zipup을 열 수 없습니다.');
};
return (
<>
<Button title="Zipup 열기" onPress={handleOpen} />
{ready && <Text>연동 준비됨</Text>}
</>
);
}Part 5. 이벤트 & 라이프사이클
5.1 이벤트 요약
| 이벤트 | 설명 | 사용 시 참고 |
| ------- | ------------------------ | ---------------------------------------------------------------------------------------------- |
| onOpen | SDK 열림 (URL 포함 가능) | data.url이 있으면 외부 브라우저 등으로 열 때 Linking.openURL(data.url) 사용. |
| ready | SDK 준비 완료 | 로딩 UI 숨기기, "준비됨" 상태로 전환할 때 활용. 10초 타임아웃이 이 이벤트 수신 시 해제됨. |
| onClose | SDK 종료 | 화면 닫힘 처리, 상태 초기화. 필요 시 setTimeout(() => close(), 0)로 한 번 더 닫기 호출 가능. |
5.2 타임아웃 정책
open()호출 시 10초 대기ready미수신 시 자동close()onOpen + url이후 다시 10초 준비 타임아웃 적용
5.3 전체 흐름
init
→ open
→ ready (정상 유지)
→ timeout (자동 close)
onOpen(url)
→ 외부 브라우저 이동
→ ready 대기
→ timeout 시 closePart 6. 네이티브 연동 구조
6.1 아키텍처
- JS → TurboModule
- Android: Kotlin + AAR
- iOS: XCFramework + Native Module
6.2 Android
| 구성 | 설명 | | ----------------------------- | ----------- | | ZipupOpenapiSdkModule.kt | 브리지 구현 | | zipup-sdk-android-release.aar | 공식 SDK |
6.3 iOS
- Podspec으로 XCFramework 링크
- TurboModule / NativeModule 방식
6.4 이벤트 포맷
{
event: string;
data?: string; // JSON 문자열
}JS에서 파싱 후 ZipupEventData로 전달됩니다.
부록: 사용 시 주의사항 및 팁
- 컴포넌트 언마운트 시: 반드시
removeListener(구독객체)를 호출하세요.useEffect의 cleanup에서return () => removeListener(sub)형태로 두면 됩니다. - 이벤트 콜백 안에서
close()호출: 동기적으로 호출하면 같은 스택에서 네이티브가 닫혀 이상 동작할 수 있으므로,setTimeout(() => close(), 0)등으로 한 틱 미뤄서 호출하는 것을 권장합니다. - init 실패 시:
open()을 호출하지 마세요. 사용자에게 "잠시 후 다시 시도해 주세요" 등의 안내를 하고, 필요하면 재초기화 로직을 두는 것이 좋습니다. open()호출 전: 반드시init()이 성공한 뒤이고, 이벤트를 처리할addListener도 미리 등록해 두는 것이 안전합니다.
