버전 표시 오류 수정
This commit is contained in:
@@ -1,20 +1,6 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
// 버전 정보를 properties 파일에서 동적으로 로드
|
// 버전 정보를 properties 파일에서 동적으로 로드
|
||||||
def versionPropsFile = rootProject.file('version.properties')
|
|
||||||
def versionProps = new Properties()
|
|
||||||
if (versionPropsFile.exists()) {
|
|
||||||
versionPropsFile.withInputStream { stream -> versionProps.load(stream) }
|
|
||||||
}
|
|
||||||
|
|
||||||
def versionName = versionProps['versionName'] ?: "1.1.1.2"
|
|
||||||
def versionCode = (versionProps['versionCode'] ?: "6").toInteger()
|
|
||||||
def buildNumber = (versionProps['buildNumber'] ?: "6").toInteger()
|
|
||||||
|
|
||||||
// 버전 정보 로깅
|
|
||||||
println "버전 정보 로드: versionName=${versionName}, versionCode=${versionCode}, buildNumber=${buildNumber}"
|
|
||||||
|
|
||||||
// 버전 정보를 직접 설정
|
|
||||||
android {
|
android {
|
||||||
namespace "com.lovable.zellyfinance"
|
namespace "com.lovable.zellyfinance"
|
||||||
compileSdk rootProject.ext.compileSdkVersion
|
compileSdk rootProject.ext.compileSdkVersion
|
||||||
@@ -22,10 +8,48 @@ android {
|
|||||||
applicationId "com.lovable.zellyfinance"
|
applicationId "com.lovable.zellyfinance"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode = versionCode
|
|
||||||
versionName = versionName
|
// version.properties 파일 로드
|
||||||
// 빌드 번호 추가 - BuildConfig 필드로 정의
|
def versionPropsFile = file("${rootDir}/version.properties")
|
||||||
buildConfigField("int", "BUILD_NUMBER", String.valueOf(buildNumber))
|
def versionProps = new Properties()
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (versionPropsFile.canRead()) {
|
||||||
|
versionProps.load(new FileInputStream(versionPropsFile))
|
||||||
|
println "버전 정보 로드: versionName=${versionProps['versionName']}, versionCode=${versionProps['versionCode']}, buildNumber=${versionProps['buildNumber']}"
|
||||||
|
} else {
|
||||||
|
println "version.properties 파일을 읽을 수 없음, 기본값 사용"
|
||||||
|
versionProps['versionName'] = '1.1.1.2'
|
||||||
|
versionProps['versionCode'] = '6'
|
||||||
|
versionProps['buildNumber'] = '6'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
println "버전 정보 로드 오류, 기본값 사용: ${e.message}"
|
||||||
|
versionProps['versionName'] = '1.1.1.2'
|
||||||
|
versionProps['versionCode'] = '6'
|
||||||
|
versionProps['buildNumber'] = '6'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 빈 문자열이나 null 값 검사
|
||||||
|
if (!versionProps['versionName'] || versionProps['versionName'].trim().isEmpty()) {
|
||||||
|
versionProps['versionName'] = '1.1.1.2'
|
||||||
|
}
|
||||||
|
if (!versionProps['versionCode'] || versionProps['versionCode'].trim().isEmpty()) {
|
||||||
|
versionProps['versionCode'] = '6'
|
||||||
|
}
|
||||||
|
if (!versionProps['buildNumber'] || versionProps['buildNumber'].trim().isEmpty()) {
|
||||||
|
versionProps['buildNumber'] = '6'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 빌드 정보 설정
|
||||||
|
versionName versionProps['versionName']
|
||||||
|
versionCode versionProps['versionCode'] ? versionProps['versionCode'].toInteger() : 6
|
||||||
|
|
||||||
|
// 빌드 설정에 BuildConfig 필드 추가
|
||||||
|
buildConfigField "String", "VERSION_NAME", "\"${versionProps['versionName']}\""
|
||||||
|
buildConfigField "int", "VERSION_CODE", "${versionProps['versionCode'] ? versionProps['versionCode'].toInteger() : 6}"
|
||||||
|
buildConfigField "int", "BUILD_NUMBER", "${versionProps['buildNumber'] ? versionProps['buildNumber'].toInteger() : 6}"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
aaptOptions {
|
aaptOptions {
|
||||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||||
|
|||||||
@@ -21,33 +21,91 @@ public class BuildInfoPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
public void getBuildInfo(PluginCall call) {
|
public void getBuildInfo(PluginCall call) {
|
||||||
|
// 오류가 발생하더라도 앱이 강제종료되지 않도록 전체 try-catch 블록 사용
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "빌드 정보 요청 수신됨");
|
Log.d(TAG, "빌드 정보 요청 수신됨");
|
||||||
|
|
||||||
JSObject ret = new JSObject();
|
JSObject ret = new JSObject();
|
||||||
|
String versionName = "";
|
||||||
|
int versionCode = 0;
|
||||||
|
int buildNumber = 0;
|
||||||
|
|
||||||
// BuildConfig에서 동적으로 버전 정보 가져오기
|
// 모든 필드 접근에 각각 try-catch 적용하여 실패하더라도 기본값 사용
|
||||||
String versionName = BuildConfig.VERSION_NAME;
|
|
||||||
int versionCode = BuildConfig.VERSION_CODE;
|
|
||||||
int buildNumber;
|
|
||||||
|
|
||||||
// 빌드 넘버는 커스텀 필드이므로 try-catch로 확인
|
|
||||||
try {
|
try {
|
||||||
buildNumber = BuildConfig.BUILD_NUMBER;
|
// Class.forName으로 BuildConfig 클래스 안전하게 접근
|
||||||
Log.d(TAG, "BuildConfig.BUILD_NUMBER: " + buildNumber);
|
Class<?> buildConfigClass = null;
|
||||||
|
try {
|
||||||
|
buildConfigClass = Class.forName("com.lovable.zellyfinance.BuildConfig");
|
||||||
|
Log.d(TAG, "BuildConfig 클래스 로드 성공");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
Log.e(TAG, "BuildConfig 클래스를 찾을 수 없음", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildConfigClass != null) {
|
||||||
|
// VERSION_NAME 필드 접근
|
||||||
|
try {
|
||||||
|
Object versionNameObj = buildConfigClass.getField("VERSION_NAME").get(null);
|
||||||
|
if (versionNameObj != null) {
|
||||||
|
versionName = versionNameObj.toString();
|
||||||
|
Log.d(TAG, "VERSION_NAME 로드 성공: " + versionName);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "VERSION_NAME 필드 접근 오류", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// VERSION_CODE 필드 접근
|
||||||
|
try {
|
||||||
|
Object versionCodeObj = buildConfigClass.getField("VERSION_CODE").get(null);
|
||||||
|
if (versionCodeObj != null) {
|
||||||
|
versionCode = Integer.parseInt(versionCodeObj.toString());
|
||||||
|
Log.d(TAG, "VERSION_CODE 로드 성공: " + versionCode);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "VERSION_CODE 필드 접근 오류", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BUILD_NUMBER 필드 접근
|
||||||
|
try {
|
||||||
|
Object buildNumberObj = buildConfigClass.getField("BUILD_NUMBER").get(null);
|
||||||
|
if (buildNumberObj != null) {
|
||||||
|
buildNumber = Integer.parseInt(buildNumberObj.toString());
|
||||||
|
Log.d(TAG, "BUILD_NUMBER 로드 성공: " + buildNumber);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "BUILD_NUMBER 필드 접근 오류, 버전 코드로 대체", e);
|
||||||
|
// 빌드 넘버 필드가 없으면 버전 코드와 동일하게 설정
|
||||||
|
buildNumber = versionCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "BUILD_NUMBER 필드 접근 오류, 기본값 사용", e);
|
Log.e(TAG, "BuildConfig 접근 중 예기치 않은 오류", e);
|
||||||
buildNumber = versionCode; // 빌드 넘버가 없으면 버전 코드와 동일하게 설정
|
}
|
||||||
|
|
||||||
|
// 버전 정보가 유효하지 않을 경우 version.properties 파일의 값이
|
||||||
|
// 빌드 과정에서 이미 BuildConfig에 적용되었을 것이므로 별도의 하드코딩 없음
|
||||||
|
if (versionName == null || versionName.isEmpty()) {
|
||||||
|
Log.w(TAG, "버전명이 비어있음, BuildConfig에서 값을 가져오지 못함");
|
||||||
|
}
|
||||||
|
if (versionCode <= 0) {
|
||||||
|
Log.w(TAG, "버전 코드가 유효하지 않음, BuildConfig에서 값을 가져오지 못함");
|
||||||
|
}
|
||||||
|
if (buildNumber <= 0) {
|
||||||
|
Log.w(TAG, "빌드 번호가 유효하지 않음, BuildConfig에서 값을 가져오지 못함");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 디버깅을 위한 로그 출력
|
// 디버깅을 위한 로그 출력
|
||||||
Log.d(TAG, "BuildConfig 클래스: " + BuildConfig.class.getName());
|
Log.d(TAG, "최종 버전명: " + versionName);
|
||||||
Log.d(TAG, "버전명: " + versionName);
|
Log.d(TAG, "최종 버전 코드: " + versionCode);
|
||||||
Log.d(TAG, "버전 코드: " + versionCode);
|
Log.d(TAG, "최종 빌드 번호: " + buildNumber);
|
||||||
Log.d(TAG, "빌드 번호: " + buildNumber);
|
|
||||||
|
|
||||||
String packageName = getContext().getPackageName();
|
String packageName = "";
|
||||||
Log.d(TAG, "패키지명: " + packageName);
|
try {
|
||||||
|
packageName = getContext().getPackageName();
|
||||||
|
Log.d(TAG, "패키지명: " + packageName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "패키지명 가져오기 오류", e);
|
||||||
|
packageName = "com.lovable.zellyfinance";
|
||||||
|
}
|
||||||
|
|
||||||
// 결과 객체에 값 설정
|
// 결과 객체에 값 설정
|
||||||
ret.put("versionName", versionName);
|
ret.put("versionName", versionName);
|
||||||
@@ -67,20 +125,23 @@ public class BuildInfoPlugin extends Plugin {
|
|||||||
// 오류 로깅 강화
|
// 오류 로깅 강화
|
||||||
Log.e(TAG, "빌드 정보 가져오기 오류", e);
|
Log.e(TAG, "빌드 정보 가져오기 오류", e);
|
||||||
|
|
||||||
// 오류 발생 시에도 기본 정보 반환하여 앱 중단 방지
|
// 오류 발생 시에도 정보 반환하여 앱 중단 방지
|
||||||
|
// build.gradle에서 설정한 기본값이 BuildConfig에 이미 적용되었을 것이므로
|
||||||
|
// 별도의 하드코딩 없이 기본적인 정보만 포함
|
||||||
JSObject fallbackResult = new JSObject();
|
JSObject fallbackResult = new JSObject();
|
||||||
fallbackResult.put("versionName", "1.1.1.2"); // 버전명 기본값
|
|
||||||
fallbackResult.put("versionCode", 6); // 버전 코드 기본값
|
|
||||||
fallbackResult.put("buildNumber", 6); // 빌드 번호 기본값
|
|
||||||
fallbackResult.put("packageName", getContext().getPackageName());
|
|
||||||
fallbackResult.put("androidVersion", Build.VERSION.RELEASE);
|
|
||||||
fallbackResult.put("androidSDK", Build.VERSION.SDK_INT);
|
|
||||||
fallbackResult.put("platform", "android-fallback");
|
fallbackResult.put("platform", "android-fallback");
|
||||||
fallbackResult.put("error", e.getMessage());
|
fallbackResult.put("error", e.getMessage());
|
||||||
fallbackResult.put("timestamp", System.currentTimeMillis());
|
fallbackResult.put("androidVersion", Build.VERSION.RELEASE);
|
||||||
|
fallbackResult.put("androidSDK", Build.VERSION.SDK_INT);
|
||||||
|
|
||||||
Log.d(TAG, "오류 발생으로 기본값 반환: " + fallbackResult.toString());
|
try {
|
||||||
call.resolve(fallbackResult); // reject 대신 기본값으로 resolve
|
fallbackResult.put("packageName", getContext().getPackageName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
fallbackResult.put("packageName", "com.lovable.zellyfinance");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 응답 해결
|
||||||
|
call.resolve(fallbackResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
buildNumber=6
|
buildNumber=7
|
||||||
versionCode=6
|
versionCode=7
|
||||||
versionName=1.1.1.2
|
versionName=1.1.1.3
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
|
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
|
||||||
import { getAppVersionInfo, isAndroidPlatform, isIOSPlatform } from '@/utils/platform';
|
import { getAppVersionInfo, isAndroidPlatform, isIOSPlatform } from '@/utils/platform';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { Capacitor } from '@capacitor/core';
|
||||||
|
|
||||||
// 버전 정보 인터페이스 정의
|
// 버전 정보 인터페이스 정의
|
||||||
interface VersionInfo {
|
interface VersionInfo {
|
||||||
@@ -12,7 +13,7 @@ interface VersionInfo {
|
|||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
defaultValues?: boolean;
|
defaultValuesUsed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AppVersionInfoProps {
|
interface AppVersionInfoProps {
|
||||||
@@ -26,11 +27,14 @@ const AppVersionInfo: React.FC<AppVersionInfoProps> = ({
|
|||||||
showDevInfo = true,
|
showDevInfo = true,
|
||||||
editable = false
|
editable = false
|
||||||
}) => {
|
}) => {
|
||||||
// localStorage에서 이전에 저장된 버전 정보 가져오기
|
// 저장된 버전 정보 가져오기 (localStorage)
|
||||||
const getSavedVersionInfo = useCallback((): VersionInfo | null => {
|
const savedInfo = useMemo(() => {
|
||||||
try {
|
try {
|
||||||
const saved = localStorage.getItem('app_version_info');
|
if (typeof localStorage !== 'undefined') {
|
||||||
return saved ? JSON.parse(saved) : null;
|
const saved = localStorage.getItem('app_version_info');
|
||||||
|
return saved ? JSON.parse(saved) : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('저장된 버전 정보 파싱 오류:', e);
|
console.error('저장된 버전 정보 파싱 오류:', e);
|
||||||
return null;
|
return null;
|
||||||
@@ -39,53 +43,40 @@ const AppVersionInfo: React.FC<AppVersionInfoProps> = ({
|
|||||||
|
|
||||||
// 기본 버전 정보를 useMemo로 생성하여 불필요한 재계산 방지
|
// 기본 버전 정보를 useMemo로 생성하여 불필요한 재계산 방지
|
||||||
const defaultInfo = useMemo<VersionInfo>(() => {
|
const defaultInfo = useMemo<VersionInfo>(() => {
|
||||||
// 웹 환경에서는 더 높은 버전 정보를 기본값으로 사용
|
const platform = Capacitor.getPlatform();
|
||||||
const webDefaultInfo: VersionInfo = {
|
const isWeb = platform === 'web';
|
||||||
versionName: '1.1.1.2', // 웹 환경에서 사용할 버전 이름
|
|
||||||
buildNumber: 6, // 웹 환경에서 사용할 빌드 번호
|
if (savedInfo) {
|
||||||
versionCode: 6, // 웹 환경에서 사용할 버전 코드
|
return savedInfo;
|
||||||
platform: 'web',
|
}
|
||||||
defaultValues: false // 기본값이 아닌 것으로 설정하여 우선순위 높이기
|
|
||||||
|
const defaultVersionInfo: VersionInfo = {
|
||||||
|
versionName: isWeb ? '1.1.1.2' : '1.0.0',
|
||||||
|
buildNumber: isWeb ? 6 : 1,
|
||||||
|
versionCode: isWeb ? 6 : 1,
|
||||||
|
platform: platform,
|
||||||
|
defaultValuesUsed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
// localStorage에 저장된 정보 가져오기
|
console.log('사용할 기본 정보:', defaultVersionInfo);
|
||||||
const savedInfo = getSavedVersionInfo();
|
|
||||||
console.log('불러온 저장 정보:', savedInfo);
|
|
||||||
|
|
||||||
// 웹 환경에서는 웹 기본값, 안드로이드/iOS에서는 기존 기본값 사용
|
if (isWeb && typeof localStorage !== 'undefined') {
|
||||||
const baseDefault = (!isAndroidPlatform() && !isIOSPlatform())
|
|
||||||
? webDefaultInfo
|
|
||||||
: {
|
|
||||||
versionName: '1.0.0',
|
|
||||||
buildNumber: 1,
|
|
||||||
versionCode: 1,
|
|
||||||
platform: 'default',
|
|
||||||
defaultValues: true
|
|
||||||
};
|
|
||||||
|
|
||||||
// 저장된 정보가 있으면 우선 사용, 없으면 기본값 사용
|
|
||||||
const result = savedInfo || baseDefault;
|
|
||||||
console.log('사용할 기본 정보:', result);
|
|
||||||
|
|
||||||
// localStorage에 초기 정보 저장 (웹에서만)
|
|
||||||
if (!savedInfo && !isAndroidPlatform() && !isIOSPlatform()) {
|
|
||||||
try {
|
try {
|
||||||
console.log('웹 기본 정보를 localStorage에 초기 저장');
|
localStorage.setItem('app_version_info', JSON.stringify(defaultVersionInfo));
|
||||||
localStorage.setItem('app_version_info', JSON.stringify(result));
|
console.log('localStorage에 초기 버전 정보 저장됨');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('초기 정보 저장 실패:', e);
|
console.error('localStorage에 초기 버전 정보 저장 실패:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return defaultVersionInfo;
|
||||||
}, [getSavedVersionInfo]);
|
}, [savedInfo]);
|
||||||
|
|
||||||
const [versionInfo, setVersionInfo] = useState<VersionInfo>(defaultInfo);
|
const [versionInfo, setVersionInfo] = useState<VersionInfo>(defaultInfo);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
const [retries, setRetries] = useState(0);
|
const [retries, setRetries] = useState(0);
|
||||||
|
|
||||||
// 버전 정보 가져오기
|
|
||||||
const fetchVersionInfo = useCallback(async () => {
|
const fetchVersionInfo = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(false);
|
setError(false);
|
||||||
@@ -94,82 +85,56 @@ const AppVersionInfo: React.FC<AppVersionInfoProps> = ({
|
|||||||
console.log('현재 플랫폼은',
|
console.log('현재 플랫폼은',
|
||||||
isAndroidPlatform() ? 'Android' : isIOSPlatform() ? 'iOS' : '웹');
|
isAndroidPlatform() ? 'Android' : isIOSPlatform() ? 'iOS' : '웹');
|
||||||
|
|
||||||
// 재시도를 하는 경우 짧은 지연 추가
|
|
||||||
if (retries > 0) {
|
if (retries > 0) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 300));
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
}
|
}
|
||||||
|
|
||||||
// localStorage에서 저장된 값을 먼저 확인
|
|
||||||
const savedInfo = getSavedVersionInfo();
|
|
||||||
|
|
||||||
// 웹 환경에서는 저장된 값이 있으면 바로 사용
|
|
||||||
if (!isAndroidPlatform() && !isIOSPlatform() && savedInfo && !savedInfo.defaultValues) {
|
|
||||||
console.log('웹 환경에서 저장된 버전 정보 사용:', savedInfo);
|
|
||||||
setVersionInfo(savedInfo);
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 네이티브 환경이거나 저장된 값이 없는 경우에만 플러그인 호출
|
|
||||||
const info = await getAppVersionInfo();
|
const info = await getAppVersionInfo();
|
||||||
console.log('받은 앱 버전 정보:', info);
|
console.log('받은 앱 버전 정보:', info);
|
||||||
|
|
||||||
// 데이터 검증 - 유효한 버전 정보인지 확인
|
|
||||||
if (!info || typeof info !== 'object') {
|
if (!info || typeof info !== 'object') {
|
||||||
throw new Error('유효하지 않은 응답 형식');
|
throw new Error('유효하지 않은 응답 형식');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 타입 안전성을 위한 변환 함수
|
const parseVersionInfo = (data: Record<string, unknown>): VersionInfo => {
|
||||||
const parseVersionInfo = (data: any): VersionInfo => {
|
|
||||||
// 빌드 번호 변환
|
|
||||||
let buildNumber: number = defaultInfo.buildNumber;
|
let buildNumber: number = defaultInfo.buildNumber;
|
||||||
if (typeof data.buildNumber === 'number') {
|
if (typeof data.buildNumber === 'number') {
|
||||||
buildNumber = data.buildNumber;
|
buildNumber = data.buildNumber;
|
||||||
} else if (typeof data.buildNumber === 'string' && data.buildNumber.trim() !== '') {
|
} else if (typeof data.buildNumber === 'string') {
|
||||||
const parsed = parseInt(data.buildNumber, 10);
|
const parsed = parseInt(data.buildNumber, 10);
|
||||||
if (!isNaN(parsed)) buildNumber = parsed;
|
if (!isNaN(parsed)) buildNumber = parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 버전 코드 변환
|
|
||||||
let versionCode: number | undefined = defaultInfo.versionCode;
|
let versionCode: number | undefined = defaultInfo.versionCode;
|
||||||
if (typeof data.versionCode === 'number') {
|
if (typeof data.versionCode === 'number') {
|
||||||
versionCode = data.versionCode;
|
versionCode = data.versionCode;
|
||||||
} else if (typeof data.versionCode === 'string' && data.versionCode.trim() !== '') {
|
} else if (typeof data.versionCode === 'string') {
|
||||||
const parsed = parseInt(data.versionCode, 10);
|
const parsed = parseInt(data.versionCode as string, 10);
|
||||||
if (!isNaN(parsed)) versionCode = parsed;
|
if (!isNaN(parsed)) versionCode = parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 응답 객체 구성
|
|
||||||
return {
|
return {
|
||||||
versionName: typeof data.versionName === 'string' && data.versionName.trim() !== ''
|
versionName: typeof data.versionName === 'string' && data.versionName.trim() !== ''
|
||||||
? data.versionName
|
? data.versionName as string
|
||||||
: defaultInfo.versionName,
|
: defaultInfo.versionName,
|
||||||
buildNumber,
|
buildNumber,
|
||||||
versionCode,
|
versionCode,
|
||||||
platform: typeof data.platform === 'string' ? data.platform : defaultInfo.platform,
|
platform: data.platform as string || defaultInfo.platform,
|
||||||
pluginResponse: typeof data.pluginResponse === 'string'
|
pluginResponse: typeof data.pluginResponse === 'string'
|
||||||
? data.pluginResponse
|
? data.pluginResponse
|
||||||
: JSON.stringify(data),
|
: JSON.stringify(data),
|
||||||
timestamp: typeof data.timestamp === 'number' ? data.timestamp : Date.now(),
|
timestamp: typeof data.timestamp === 'number' ? data.timestamp : Date.now(),
|
||||||
defaultValues: false
|
defaultValuesUsed: false
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 타입 변환 및 정제
|
|
||||||
const newVersionInfo = parseVersionInfo(info);
|
const newVersionInfo = parseVersionInfo(info);
|
||||||
|
|
||||||
// 웹 환경에서는 defaultValues가 true인 경우(기본값) localStorage 값 우선 적용
|
|
||||||
if (!isAndroidPlatform() && !isIOSPlatform() && newVersionInfo.defaultValues && savedInfo) {
|
|
||||||
console.log('웹 환경의 기본값 대신 저장된 값 사용');
|
|
||||||
setVersionInfo(savedInfo);
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LocalStorage에 버전 정보 저장
|
|
||||||
try {
|
try {
|
||||||
localStorage.setItem('app_version_info', JSON.stringify(newVersionInfo));
|
if (typeof localStorage !== 'undefined') {
|
||||||
console.log('버전 정보가 localStorage에 저장됨:', newVersionInfo);
|
localStorage.setItem('app_version_info', JSON.stringify(newVersionInfo));
|
||||||
|
console.log('버전 정보가 localStorage에 저장됨:', newVersionInfo);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('버전 정보 저장 실패:', e);
|
console.warn('버전 정보 저장 실패:', e);
|
||||||
}
|
}
|
||||||
@@ -181,63 +146,94 @@ const AppVersionInfo: React.FC<AppVersionInfoProps> = ({
|
|||||||
console.error('버전 정보 가져오기 실패:', error);
|
console.error('버전 정보 가져오기 실패:', error);
|
||||||
setError(true);
|
setError(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
// 오류 발생 시 기존 저장된 값 유지 (초기화 방지)
|
|
||||||
console.log('오류 발생으로 기본값 사용');
|
|
||||||
}
|
}
|
||||||
}, [retries, defaultInfo]);
|
}, [retries, defaultInfo]);
|
||||||
|
|
||||||
// 재시도 처리
|
|
||||||
const handleRetry = useCallback(() => {
|
const handleRetry = useCallback(() => {
|
||||||
setRetries(prev => prev + 1);
|
setRetries(prev => prev + 1);
|
||||||
fetchVersionInfo();
|
fetchVersionInfo();
|
||||||
}, [fetchVersionInfo]);
|
}, [fetchVersionInfo]);
|
||||||
|
|
||||||
// 초기화 완료 후 한번 더 시도하도록 설정
|
|
||||||
const initialLoadAttemptedRef = useRef(false);
|
const initialLoadAttemptedRef = useRef(false);
|
||||||
|
|
||||||
// 컴포넌트 마운트 시 즉시 실행 (IIFE)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 초기화 직후 localStorage 확인
|
let isMounted = true;
|
||||||
console.log('컴포넌트 마운트 시 localStorage 확인:', localStorage.getItem('app_version_info'));
|
|
||||||
|
|
||||||
let isMounted = true;
|
const loadVersionInfo = async () => {
|
||||||
|
console.log('앱 버전 정보 로딩 시작');
|
||||||
(async () => {
|
|
||||||
// 즉시 버전 정보 가져오기 시도
|
try {
|
||||||
await fetchVersionInfo();
|
if (savedInfo && isMounted) {
|
||||||
|
console.log('저장된 정보로 먼저 표시:', savedInfo);
|
||||||
// 컴포넌트가 언마운트되었는지 확인
|
setVersionInfo(savedInfo);
|
||||||
if (!isMounted) return;
|
}
|
||||||
|
|
||||||
// 1000ms 후에 한번 더 시도 (네이티브 플러그인이 완전히 로드되지 않았을 경우 대비)
|
const newVersionInfo = await getAppVersionInfo();
|
||||||
setTimeout(() => {
|
|
||||||
if (!isMounted) return;
|
if (!isMounted) return;
|
||||||
|
|
||||||
if (error || loading) {
|
console.log('불러온 버전 정보:', newVersionInfo);
|
||||||
fetchVersionInfo();
|
|
||||||
initialLoadAttemptedRef.current = true;
|
if (!isAndroidPlatform() && !isIOSPlatform() &&
|
||||||
|
'defaultValuesUsed' in newVersionInfo &&
|
||||||
|
newVersionInfo.defaultValuesUsed === true &&
|
||||||
|
savedInfo) {
|
||||||
|
console.log('웹 환경의 기본값 대신 저장된 값 사용');
|
||||||
|
setVersionInfo(savedInfo);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, 1000);
|
|
||||||
})();
|
try {
|
||||||
|
if (typeof localStorage !== 'undefined') {
|
||||||
// 개발 모드에서는 버전 정보 변경을 쉽게 확인하기 위해 주기적 갱신
|
localStorage.setItem('app_version_info', JSON.stringify(newVersionInfo));
|
||||||
let interval: number | undefined;
|
console.log('버전 정보가 localStorage에 저장됨:', newVersionInfo);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
}
|
||||||
interval = window.setInterval(() => {
|
} catch (e) {
|
||||||
|
console.warn('버전 정보 저장 실패:', e);
|
||||||
|
}
|
||||||
|
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
fetchVersionInfo();
|
setVersionInfo(newVersionInfo);
|
||||||
|
setLoading(false);
|
||||||
|
console.log('앱 버전 정보 표시 준비 완료');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('버전 정보 가져오기 실패:', error);
|
||||||
|
|
||||||
|
if (isMounted) {
|
||||||
|
const fallbackInfo = savedInfo || defaultInfo;
|
||||||
|
console.log('오류 발생으로 대체 정보 사용:', fallbackInfo);
|
||||||
|
setVersionInfo(fallbackInfo);
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, 30000); // 30초마다 새로 가져오기
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
isMounted = false;
|
|
||||||
if (interval) {
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [fetchVersionInfo, error, loading]);
|
|
||||||
|
loadVersionInfo();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
|
}, [savedInfo, defaultInfo]);
|
||||||
|
|
||||||
|
const renderDevInfo = () => {
|
||||||
|
if (versionInfo && showDevInfo) {
|
||||||
|
return (
|
||||||
|
<div className="mt-2 text-xs text-muted-foreground">
|
||||||
|
<div>
|
||||||
|
<span className="font-semibold">앱 플랫폼:</span> {versionInfo.platform || 'unknown'}
|
||||||
|
</div>
|
||||||
|
{versionInfo.defaultValuesUsed && (
|
||||||
|
<div className="text-yellow-600 dark:text-yellow-400">
|
||||||
|
⚠️ 기본값 사용 중: 실제 버전 정보를 가져오지 못했습니다
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
@@ -276,6 +272,7 @@ const AppVersionInfo: React.FC<AppVersionInfoProps> = ({
|
|||||||
{editable && (
|
{editable && (
|
||||||
<p className="text-gray-400 font-semibold text-sm mt-2">ZELLYY CLOUD</p>
|
<p className="text-gray-400 font-semibold text-sm mt-2">ZELLYY CLOUD</p>
|
||||||
)}
|
)}
|
||||||
|
{renderDevInfo()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user