
npx create-expo-app@latest my-app --template blank-typescript
npm install @tencentcloud/chat-uikit-react-native tuikit-atomicx-react-native
yarn add @tencentcloud/chat-uikit-react-native
chat-uikit-react-native 依赖语音录制、图片选择件选择、国际化等 native module,需要手动安装。npm install react-i18next i18next react-native-nitro-modules react-native-nitro-sound react-native-video react-native-create-thumbnail react-native-image-picker @react-native-documents/picker @react-native-async-storage/async-storage react-native-safe-area-context react-native-screens
yarn add react-i18next i18next react-native-nitro-modules react-native-nitro-sound react-native-video react-native-create-thumbnail react-native-image-picker @react-native-documents/picker @react-native-async-storage/async-storage react-native-safe-area-context react-native-screens
chat-uikit-react-native 下 Screen 使用 @react-navigation/native 进行路由管理。npx expo install @react-navigation/native @react-navigation/native-stack
app.json 中配置 android、iOS 的相关权限。{"expo": {"ios": {"infoPlist": {"NSCameraUsageDescription": "需要使用相机来拍照发送图片和视频","NSPhotoLibraryUsageDescription": "需要访问相册来选择图片和视频发送","NSPhotoLibraryAddUsageDescription": "需要保存图片到相册","NSMicrophoneUsageDescription": "需要使用麦克风来录制语音消息","NSDocumentsFolderUsageDescription": "需要访问文件来选择文档发送"}},"android": {"permissions": ["CAMERA","RECORD_AUDIO","READ_EXTERNAL_STORAGE","WRITE_EXTERNAL_STORAGE","READ_MEDIA_IMAGES","READ_MEDIA_VIDEO","READ_MEDIA_AUDIO","ACCESS_NETWORK_STATE","ACCESS_WIFI_STATE","VIBRATE","WAKE_LOCK"]}}}
@tencentcloud/chat-uikit-react-native/src/screens 拷贝到 ./src/screens 下(方便自定义 / 调整路由等)。cp -R node_modules/@tencentcloud/chat-uikit-react-native/src/screens ./src/screens/
xcopy /E /I /Y "node_modules\\@tencentcloud\\chat-uikit-react-native\\src\\screens" ".\\src\\screens"
app.tsx 内容为如下内容。@react-navigation/native 如需替换,需要同步替换 ./src/screens 中的相关路由。import React, { useState } from 'react'import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native'import { SafeAreaProvider } from 'react-native-safe-area-context'import { NavigationContainer } from '@react-navigation/native'import { createNativeStackNavigator } from '@react-navigation/native-stack'import {LoginScreen,ChatScreen,ChatSettingScreen,ConversationListScreen,ContactListScreen,SearchScreen,AddFriendScreen,AddGroupScreen,ApplicationVerifyScreen,BlackListScreen,ContactInfoScreen,FriendApplicationListScreen,GroupApplicationListScreen,GroupListScreen,SetRemarkScreen,GroupManagementScreen,GroupMemberListScreen,GroupTypeInfoScreen,CreateGroupScreen,SearchInConversationScreen,UserFilterScreen,UserPickerScreen,BottomTabBar,type BottomTabKey,} from './src/screens'import { ToastRoot } from '@tencentcloud/chat-uikit-react-native'const Stack = createNativeStackNavigator()const MainScreen: React.FC = () => {const [activeTab, setActiveTab] = useState<BottomTabKey>('message')return (<View style={styles.mainScreen}>{activeTab === 'message' ? (<ConversationListScreen />) : (<ContactListScreen />)}<BottomTabBar current={activeTab} onChange={setActiveTab} /></View>)}function App(): React.JSX.Element {const isDarkMode = useColorScheme() === 'dark'return (<SafeAreaProvider><StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /><ToastRoot /><NavigationContainer><Stack.NavigatorinitialRouteName="Login"screenOptions={{ headerShown: false }}><Stack.Screen name="Login" component={LoginScreen} /><Stack.Screen name="Main" component={MainScreen} options={{ freezeOnBlur: true }} /><Stack.Screen name="Chat" component={ChatScreen} /><Stack.Screen name="Search" component={SearchScreen} /><Stack.Screen name="ChatSetting" component={ChatSettingScreen} options={{ freezeOnBlur: true }} /><Stack.Screen name="AddFriend" component={AddFriendScreen} /><Stack.Screen name="AddGroup" component={AddGroupScreen} /><Stack.Screen name="ApplicationVerify" component={ApplicationVerifyScreen} /><Stack.Screen name="BlackList" component={BlackListScreen} /><Stack.Screen name="ContactInfo" component={ContactInfoScreen} /><Stack.Screen name="FriendApplicationList" component={FriendApplicationListScreen} /><Stack.Screen name="GroupApplicationList" component={GroupApplicationListScreen} /><Stack.Screen name="GroupList" component={GroupListScreen} /><Stack.Screen name="SetRemark" component={SetRemarkScreen} /><Stack.Screen name="GroupManagement" component={GroupManagementScreen} /><Stack.Screen name="GroupMemberList" component={GroupMemberListScreen} /><Stack.Screen name="GroupTypeInfo" component={GroupTypeInfoScreen} /><Stack.Screen name="CreateGroup" component={CreateGroupScreen} /><Stack.Screen name="SearchInConversation" component={SearchInConversationScreen} /><Stack.Screen name="UserFilter" component={UserFilterScreen} /><Stack.Screen name="UserPicker" component={UserPickerScreen} /></Stack.Navigator></NavigationContainer></SafeAreaProvider>)}const styles = StyleSheet.create({mainScreen: {flex: 1,backgroundColor: '#F5F5F5',},})export default App
src/screens/LoginScreen.tsx 中,填入 SDKAppID、 userID、userSig,点击登录。参数 | 类型 | 说明 |
SDKAppID | Number | ![]() |
SecretKey | String | |
userID | String | 用户的唯一标识符,由您定义,只能包含大小写字母(a-z,A-Z)、数字(0-9)、下划线和连字符。 |
userSig | String | 用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文。您可以在 即时通信 Chat 控制台 > 开发工具 > UserSig 工具,填写创建的 UserID,即可生成 UserSig。 安全提示: 示例支持通过 genTestUserSig 函数生成 userSig。该方法中 SecretKey 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量。该方法仅适合本地跑通功能调试。 正确的 UserSig 签发方式请参见 服务端生成 UserSig。示例代码中的 UserSig 仅供测试使用,生产环境请通过 服务端生成。 敏感信息(UserSig/SecretKey)仅用于 Demo 测试,不可提交到代码仓库或用于生产环境。 |
import React, { useEffect, useState } from 'react'import { useNavigation } from '@react-navigation/native'import type { NativeStackNavigationProp } from '@react-navigation/native-stack'import { useLoginState } from 'tuikit-atomicx-react-native'import { genTestUserSig } from './debug/GenerateTestUserSig'type RootStackParamList = {Login: undefinedMain: undefined}type Nav = NativeStackNavigationProp<RootStackParamList, 'Login'>export const LoginScreen: React.FC = () => {const navigation = useNavigation<Nav>()const [loading, setLoading] = useState(false)const { login, logout, loginStatus, loginUserInfo } = useLoginState()const [userID, setUserID] = useState('') // userIDconst SDKAppID = 0 // SDKAppIDconst SecretKey = '' // SecretKeyuseEffect((): void => {if (loading && loginStatus === 1) {navigation.reset({ index: 0, routes: [{ name: 'Main' }] })}}, [loading, loginStatus, navigation])const doLogin = async (): Promise<void> => {setLoading(true)try {await login({sdkAppID: Number(SDKAppID),userID: userID.trim(),userSig: genTestUserSig({SDKAppID: SDKAppID,userID: userID.trim(),SecretKey: SecretKey}).userSig,})} catch (error: any) {console.error(error)} finally {setLoading(false)}}return /* UI */;}
npm run android 编译运行项目。npm run android
cd iospod install
cd ../npm run ios
npx react-native doctor
文档反馈