You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native/安卓/iOS应用:如何区分首次安装与版本更新用户?

嘿,这个需求太常见啦!很多App都会给老用户展示更新日志,新用户直接上手就行。我来给你详细说说React Native跨平台、安卓原生、iOS原生三种实现方式,你可以根据自己的项目情况选~

React Native 跨平台实现方案

跨平台方案的核心思路是存储并对比App版本号:每次启动时,拿当前版本和本地存储的历史版本做对比,判断是首次安装、版本更新还是常规启动。

依赖准备

我们需要两个库:获取App版本信息的react-native-device-info,以及存储版本号的@react-native-async-storage/async-storage(如果追求性能,也可以用react-native-mmkv,同步存储更快)。

先安装依赖:

# npm
npm install react-native-device-info @react-native-async-storage/async-storage

# yarn
yarn add react-native-device-info @react-native-async-storage/async-storage

核心代码实现

在你的首屏组件里加入版本检测逻辑:

import { useEffect } from 'react';
import DeviceInfo from 'react-native-device-info';
import AsyncStorage from '@react-native-async-storage/async-storage';

// 检测版本状态的函数
const checkAppVersionStatus = async () => {
  try {
    // 获取当前App的版本名称(比如1.2.0),如果用构建号更精准,就用getBuildNumber()
    const currentVersion = await DeviceInfo.getVersion();
    // 读取本地存储的历史版本号
    const storedVersion = await AsyncStorage.getItem('app_last_version');

    if (!storedVersion) {
      // 本地无历史版本 → 首次安装
      await AsyncStorage.setItem('app_last_version', currentVersion);
      console.log('首次安装,不展示更新提示');
      // 这里可以处理新用户引导逻辑
    } else if (storedVersion !== currentVersion) {
      // 历史版本≠当前版本 → 版本更新
      await AsyncStorage.setItem('app_last_version', currentVersion);
      console.log('老用户更新版本,展示更新提示');
      // 调用你的更新内容弹窗组件
      // showUpdateChangelogModal();
    } else {
      // 版本一致 → 常规启动
      console.log('常规启动,无操作');
    }
  } catch (error) {
    console.error('版本检测失败:', error);
  }
};

// 首屏加载时触发检测
const HomeScreen = () => {
  useEffect(() => {
    checkAppVersionStatus();
  }, []);

  return (
    // 你的首屏UI内容
  );
};

export default HomeScreen;

小提示

  • 如果你们团队用构建号(比如101、102)区分更新(比版本名称更精准,避免版本名称相同但构建内容不同的情况),就把getVersion()换成getBuildNumber()
  • react-native-mmkv替代AsyncStorage的话,存储逻辑会变成同步调用,代码更简洁,适合对启动性能有要求的场景。
安卓原生端实现方案

如果需要在原生层处理(比如启动时更早检测),可以用SharedPreferences存储版本号:

import android.content.SharedPreferences
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var appPrefs: SharedPreferences

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        appPrefs = getSharedPreferences("AppVersionPrefs", MODE_PRIVATE)
        
        // 获取当前版本号(Android 10+用longVersionCode,低版本用versionCode)
        val currentVersionCode = packageManager.getPackageInfo(packageName, 0).run {
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                longVersionCode
            } else {
                versionCode.toLong()
            }
        }
        val storedVersionCode = appPrefs.getLong("last_version_code", -1L)

        when {
            storedVersionCode == -1L -> {
                // 首次安装
                appPrefs.edit().putLong("last_version_code", currentVersionCode).apply()
            }
            storedVersionCode != currentVersionCode -> {
                // 版本更新,展示提示
                appPrefs.edit().putLong("last_version_code", currentVersionCode).apply()
                showUpdateChangelog()
            }
            // 版本一致,无操作
        }
    }

    private fun showUpdateChangelog() {
        // 这里实现你的更新提示逻辑,比如弹出Dialog、Toast,或者跳转到更新日志页面
    }
}
iOS原生端实现方案

iOS端可以用UserDefaults存储版本号,在AppDelegate里处理启动检测:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let defaults = UserDefaults.standard
        // 获取当前版本名称(CFBundleShortVersionString),构建号用CFBundleVersion
        let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
        let storedVersion = defaults.string(forKey: "app_last_version")
        
        if storedVersion == nil {
            // 首次安装
            defaults.set(currentVersion, forKey: "app_last_version")
        } else if storedVersion != currentVersion {
            // 版本更新,展示提示
            defaults.set(currentVersion, forKey: "app_last_version")
            showUpdateAlert()
        }
        return true
    }
    
    private func showUpdateAlert() {
        let alert = UIAlertController(
            title: "版本更新啦!",
            message: "本次更新带来了XX功能优化,快来体验吧~",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "知道了", style: .default))
        
        // 拿到当前根控制器弹出弹窗
        if let window = UIApplication.shared.windows.first, let rootVC = window.rootViewController {
            rootVC.present(alert, animated: true)
        }
    }
}

额外建议

  1. 如果你的App用了CodePush热更新,需要区分原生版本更新热更新:这时候要结合CodePush的版本号一起判断,避免每次热更新都弹出提示。
  2. 可以给更新提示加个“不再显示”的选项,把用户的选择存在本地,提升体验。
  3. 用户卸载重装App后,存储的版本号会被清除,会被识别为新用户,这是符合预期的行为。

内容的提问来源于stack exchange,提问作者cinemanja

火山引擎 最新活动