iOS 웹뷰 이미지 저장 기능 추가 (네이티브 브릿지)

- iOS 환경에서 이미지 다운로드가 안 되는 문제 해결
- 네이티브 앱 브릿지를 통한 이미지 저장 기능 구현
- iOS만 네이티브 브릿지 사용, Android/웹은 기존 방식 유지

변경사항:
- BridgeMessageType에 SAVE_IMAGE 타입 추가
- SaveImageRequest, SaveImageResponse 인터페이스 정의
- appBridge.saveImage() 메서드 구현
- cash-receipt-sample.tsx에서 iOS 환경 감지 및 네이티브 저장 처리
- 네이티브 앱 개발자를 위한 구현 가이드 문서 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jay Sheen
2025-11-12 14:41:41 +09:00
parent a163ba35a9
commit be9d103012
4 changed files with 512 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
import { IMAGE_ROOT } from '@/shared/constants/common';
import { snackBar } from '@/shared/lib';
import { snackBar, appBridge } from '@/shared/lib';
import { toPng } from 'html-to-image';
import { useTranslation } from 'react-i18next';
import '@/shared/ui/assets/css/style-tax-invoice.css';
@@ -31,17 +31,46 @@ export const CashReceiptSample = ({
}: CashReceiptSampleProps) => {
const { t } = useTranslation();
const downloadImage = () => {
const downloadImage = async () => {
const section = document.getElementById('image-section') as HTMLElement;
toPng(section).then((image) => {
const link = document.createElement('a');
link.download = 'downloadImage.png';
link.href = image;
link.click();
snackBar(t('common.imageRequested'), function(){
//onClickToClose();
});
});
try {
const imageDataUrl = await toPng(section);
// iOS 네이티브 환경인 경우 네이티브 브릿지 사용
if (appBridge.isIOS()) {
try {
// data:image/png;base64, 부분 제거하고 순수 base64 데이터만 추출
const base64Data = imageDataUrl.split(',')[1];
const fileName = `cash_receipt_${moment().format('YYYYMMDDHHmmss')}.png`;
const result = await appBridge.saveImage({
imageData: base64Data,
fileName: fileName,
mimeType: 'image/png'
});
if (result.success) {
snackBar(t('common.imageSaved'));
} else {
throw new Error(result.error || 'Failed to save image');
}
} catch (error) {
console.error('Native image save failed:', error);
snackBar(t('common.imageSaveFailed'));
}
} else {
// Android 또는 웹 환경인 경우 기존 방식 사용 (다운로드 링크)
const link = document.createElement('a');
link.download = `cash_receipt_${moment().format('YYYYMMDDHHmmss')}.png`;
link.href = imageDataUrl;
link.click();
snackBar(t('common.imageRequested'));
}
} catch (error) {
console.error('Image generation failed:', error);
snackBar(t('common.imageGenerationFailed'));
}
};
const onClickToClose = () => {
setCashReceiptSampleOn(false);