🏢 Expo 项目接入企业微信 SDK 完整指南
在 Expo 项目中集成企业微信 SDK,实现免密登录、应用内跳转等功能的完整实践教程。
📖 前言
企业微信作为企业内部主要的沟通和办公工具,与移动应用的集成能够大大提升用户体验和工作效率。本文将详细介绍如何在 Expo 项目中接入企业微信 SDK,实现以下核心功能:
- 🔐 免密登录 - 通过企微授权快速登录应用
- 🔗 深度链接 - 支持企微内打开应用页面
- 📱 应用分享 - 分享内容到企微会话
- 🚀 快速跳转 - 从应用跳转到企微指定页面
🎯 技术方案
架构设计
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 企业微信客户端 │───│ 原生 SDK 层 │───│ Expo 应用层 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
OAuth 授权 JNI/OC 接口 JS Bridge
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ 授权码 │ │ 自定义模块 │ │ React 组件 │
└───────────┘ └───────────┘ └───────────┘
技术栈
- Expo SDK 53+ - 支持自定义原生模块
- 企业微信 Android SDK - 提供原生能力
- 企业微信 iOS SDK - iOS 平台支持
- Expo Modules API - 桥接原生和 JS 层
- Deep Linking - 处理应用间跳转
🛠️ 环境准备
1. 企业微信开发环境
# 1. 注册企业微信开发者账号
# 访问:https://developer.work.weixin.qq.com/
# 2. 创建企业内部应用
# 获取以下信息:
# - CorpID(企业ID)
# - AgentID(应用ID)
# - Secret(应用密钥)
# 3. 配置应用回调域名
# 在应用配置中设置:
# - 可信域名
# - OAuth2.0 网页授权回调域名
2. 下载企业微信 SDK
# Android SDK
# 下载地址:https://developer.work.weixin.qq.com/resource/1000005
# 解压后得到 wxwork.aar 文件
# iOS SDK
# 下载地址:https://developer.work.weixin.qq.com/resource/1000005
# 解压后得到 WWKApi.framework 文件
3. 项目要求
# 确保项目支持自定义原生模块
npx expo install expo-dev-client
# 安装必要依赖
yarn add expo-linking expo-web-browser
npx expo install expo-constants
📦 SDK 集成步骤
第一步:创建自定义 Expo 模块
# 在项目根目录创建模块目录
mkdir -p modules/wework-module
# 创建模块配置文件
touch modules/wework-module/expo-module.config.json
创建 modules/wework-module/expo-module.config.json:
{
"platforms": ["ios", "android"],
"ios": {
"modules": ["WeworkModule"]
},
"android": {
"modules": ["expo.modules.weworkmodule.WeworkModule"]
}
}
第二步:Android 平台集成
1. 配置 Android 模块
创建 modules/wework-module/android/build.gradle:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
group = 'expo.modules.weworkmodule'
version = '0.1.0'
buildscript {
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
if (expoModulesCorePlugin.exists()) {
apply from: expoModulesCorePlugin
applyKotlinExpoModulesCorePlugin()
}
ext {
kotlin_version = '1.8.10'
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// 企业微信 SDK
implementation files('libs/wxwork.aar')
}
android {
compileSdkVersion safeExtGet("compileSdkVersion", 34)
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.majorVersion
}
namespace "expo.modules.weworkmodule"
defaultConfig {
minSdkVersion safeExtGet("minSdkVersion", 21)
targetSdkVersion safeExtGet("targetSdkVersion", 34)
versionCode 1
versionName "1.0.0"
}
}
repositories {
mavenCentral()
}
2. 复制 SDK 文件
# 创建 libs 目录并复制 SDK
mkdir -p modules/wework-module/android/libs
cp /path/to/wxwork.aar modules/wework-module/android/libs/
3. 创建 Android 原生模块
创建 modules/wework-module/android/src/main/java/expo/modules/weworkmodule/WeworkModule.kt:
package expo.modules.weworkmodule
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import expo.modules.kotlin.Promise
import expo.modules.kotlin.exception.Exceptions
import android.content.Context
import android.content.Intent
import com.tencent.wework.api.IWWAPI
import com.tencent.wework.api.WWAPIFactory
import com.tencent.wework.api.model.*
class WeworkModule : Module() {
private var wwapi: IWWAPI? = null
private val context: Context
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
override fun definition() = ModuleDefinition {
Name("WeworkModule")
OnCreate {
// 初始化企业微信 API
wwapi = WWAPIFactory.createWWAPI(context)
}
// 检查是否安装企业微信
AsyncFunction("isWeworkInstalled") { promise: Promise ->
try {
val isInstalled = wwapi?.isWWAppInstalled ?: false
promise.resolve(isInstalled)
} catch (e: Exception) {
promise.reject("CHECK_INSTALLATION_ERROR", e.message, e)
}
}
// 企业微信授权登录
AsyncFunction("weworkAuth") { corpId: String, agentId: String, state: String, promise: Promise ->
try {
if (wwapi?.isWWAppInstalled != true) {
promise.reject("WEWORK_NOT_INSTALLED", "企业微信未安装", null)
return@AsyncFunction
}
val req = WWAuthMessage.Req().apply {
sch = "your-app-scheme" // 应用回调 scheme
appId = corpId
agentId = agentId
state = state
}
val result = wwapi?.sendMessage(req) ?: false
if (result) {
promise.resolve(true)
} else {
promise.reject("AUTH_FAILED", "授权请求发送失败", null)
}
} catch (e: Exception) {
promise.reject("AUTH_ERROR", e.message, e)
}
}
// 打开企业微信会话
AsyncFunction("openWeworkChat") { chatId: String, promise: Promise ->
try {
val req = WWOpenChatMessage.Req().apply {
chatId = chatId
}
val result = wwapi?.sendMessage(req) ?: false
promise.resolve(result)
} catch (e: Exception) {
promise.reject("OPEN_CHAT_ERROR", e.message, e)
}
}
}
}
4. 创建回调处理 Activity
创建 modules/wework-module/android/src/main/java/expo/modules/weworkmodule/WXEntryActivity.kt:
package expo.modules.weworkmodule
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import com.tencent.wework.api.IWWAPI
import com.tencent.wework.api.IWWAPIEventHandler
import com.tencent.wework.api.WWAPIFactory
import com.tencent.wework.api.model.BaseMessage
class WXEntryActivity : Activity(), IWWAPIEventHandler {
private var wwapi: IWWAPI? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
wwapi = WWAPIFactory.createWWAPI(this)
wwapi?.handleIntent(intent, this)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
wwapi?.handleIntent(intent, this)
}
override fun onMessage(message: BaseMessage?) {
// 处理企业微信回调
when (message) {
is com.tencent.wework.api.model.WWAuthMessage.Resp -> {
handleAuthResponse(message)
}
}
finish()
}
private fun handleAuthResponse(resp: com.tencent.wework.api.model.WWAuthMessage.Resp) {
when (resp.errCode) {
0 -> {
// 授权成功,发送结果到 React Native
val intent = Intent("WEWORK_AUTH_SUCCESS").apply {
putExtra("code", resp.code)
putExtra("state", resp.state)
}
sendBroadcast(intent)
}
-2 -> {
// 用户取消
sendBroadcast(Intent("WEWORK_AUTH_CANCELLED"))
}
else -> {
// 授权失败
val intent = Intent("WEWORK_AUTH_FAILED").apply {
putExtra("errCode", resp.errCode)
putExtra("errStr", resp.errStr)
}
sendBroadcast(intent)
}
}
}
}
第三步:iOS 平台集成
1. 创建 iOS 模块配置
创建 modules/wework-module/ios/WeworkModule.podspec:
Pod::Spec.new do |s|
s.name = 'WeworkModule'
s.version = '1.0.0'
s.summary = 'A sample Expo module'
s.description = 'A sample Expo module for Wework integration'
s.author = ''
s.homepage = 'https://docs.expo.dev/modules/'
s.platforms = { :ios => '13.0', :tvos => '13.0' }
s.source = { git: '' }
s.static_framework = true
s.dependency 'ExpoModulesCore'
# 企业微信 SDK
s.vendored_frameworks = 'WWKApi.framework'
# Swift/Objective-C compatibility
s.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES',
'SWIFT_COMPILATION_MODE' => 'wholemodule'
}
s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
end
2. 复制 iOS SDK
# 复制企业微信 iOS SDK
cp -R /path/to/WWKApi.framework modules/wework-module/ios/
3. 创建 iOS 原生模块
创建 modules/wework-module/ios/WeworkModule.swift:
import ExpoModulesCore
import WWKApi
public class WeworkModule: Module {
public func definition() -> ModuleDefinition {
Name("WeworkModule")
OnCreate {
// 初始化企业微信 SDK
WWKApi.registerApp("your-corp-id")
}
// 检查是否安装企业微信
AsyncFunction("isWeworkInstalled") { (promise: Promise) in
let isInstalled = WWKApi.isAppInstalled()
promise.resolve(isInstalled)
}
// 企业微信授权登录
AsyncFunction("weworkAuth") { (corpId: String, agentId: String, state: String, promise: Promise) in
guard WWKApi.isAppInstalled() else {
promise.reject("WEWORK_NOT_INSTALLED", "企业微信未安装")
return
}
let req = WWKSendAuthReq()
req.sch = "your-app-scheme"
req.appId = corpId
req.agentId = agentId
req.state = state
let result = WWKApi.sendReq(req)
if result {
promise.resolve(true)
} else {
promise.reject("AUTH_FAILED", "授权请求发送失败")
}
}
// 打开企业微信会话
AsyncFunction("openWeworkChat") { (chatId: String, promise: Promise) in
let req = WWKOpenChatReq()
req.chatId = chatId
let result = WWKApi.sendReq(req)
promise.resolve(result)
}
}
}
第四步:JavaScript 层封装
1. 创建模块接口
创建 modules/wework-module/src/WeworkModule.ts:
import { NativeModule, requireNativeModule } from 'expo';
export interface WeworkAuthResult {
code?: string;
state?: string;
errCode?: number;
errStr?: string;
}
export interface WeworkModuleEvents {
onAuthResult: (result: WeworkAuthResult) => void;
}
class WeworkModule extends NativeModule<WeworkModuleEvents> {
/**
* 检查是否安装企业微信
*/
async isWeworkInstalled(): Promise<boolean> {
return await this.nativeModule.isWeworkInstalled();
}
/**
* 企业微信授权登录
* @param corpId 企业ID
* @param agentId 应用ID
* @param state 状态参数
*/
async weworkAuth(corpId: string, agentId: string, state: string): Promise<boolean> {
return await this.nativeModule.weworkAuth(corpId, agentId, state);
}
/**
* 打开企业微信会话
* @param chatId 会话ID
*/
async openWeworkChat(chatId: string): Promise<boolean> {
return await this.nativeModule.openWeworkChat(chatId);
}
/**
* 注册授权结果回调
*/
onAuthResult(callback: (result: WeworkAuthResult) => void): void {
this.addListener('onAuthResult', callback);
}
/**
* 移除授权结果回调
*/
removeAuthResultListener(): void {
this.removeAllListeners('onAuthResult');
}
}
export default requireNativeModule<WeworkModule>('WeworkModule');
2. 创建 React Hook
创建 modules/wework-module/src/useWework.ts:
import { useEffect, useCallback, useState } from 'react';
import { Platform } from 'react-native';
import * as Linking from 'expo-linking';
import WeworkModule, { WeworkAuthResult } from './WeworkModule';
interface UseWeworkConfig {
corpId: string;
agentId: string;
scheme: string;
}
export const useWework = (config: UseWeworkConfig) => {
const [isInstalled, setIsInstalled] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
// 检查安装状态
useEffect(() => {
const checkInstallation = async () => {
try {
const installed = await WeworkModule.isWeworkInstalled();
setIsInstalled(installed);
} catch (error) {
console.error('检查企业微信安装状态失败:', error);
setIsInstalled(false);
}
};
checkInstallation();
}, []);
// 处理深度链接回调
useEffect(() => {
const handleDeepLink = (url: string) => {
const parsed = Linking.parse(url);
if (parsed.scheme === config.scheme && parsed.hostname === 'wework') {
// 处理企业微信回调
const { code, state, errCode, errStr } = parsed.queryParams || {};
const result: WeworkAuthResult = {
code: code as string,
state: state as string,
errCode: errCode ? parseInt(errCode as string) : undefined,
errStr: errStr as string,
};
// 触发回调事件
WeworkModule.getEmitter().emit('onAuthResult', result);
}
};
const subscription = Linking.addEventListener('url', ({ url }) => {
handleDeepLink(url);
});
// 检查应用启动时的 URL
Linking.getInitialURL().then((url) => {
if (url) {
handleDeepLink(url);
}
});
return () => {
subscription?.remove();
};
}, [config.scheme]);
// 企业微信授权登录
const login = useCallback(async (state?: string): Promise<WeworkAuthResult> => {
if (!isInstalled) {
throw new Error('企业微信未安装');
}
setIsLoading(true);
return new Promise((resolve, reject) => {
const authState = state || `auth_${Date.now()}`;
// 注册一次性回调
const handleAuthResult = (result: WeworkAuthResult) => {
WeworkModule.removeAuthResultListener();
setIsLoading(false);
if (result.errCode === 0 || result.code) {
resolve(result);
} else {
reject(new Error(result.errStr || '授权失败'));
}
};
WeworkModule.onAuthResult(handleAuthResult);
// 发起授权请求
WeworkModule.weworkAuth(config.corpId, config.agentId, authState)
.catch((error) => {
WeworkModule.removeAuthResultListener();
setIsLoading(false);
reject(error);
});
});
}, [isInstalled, config]);
// 打开企业微信会话
const openChat = useCallback(async (chatId: string): Promise<boolean> => {
if (!isInstalled) {
throw new Error('企业微信未安装');
}
return await WeworkModule.openWeworkChat(chatId);
}, [isInstalled]);
return {
isInstalled,
isLoading,
login,
openChat,
};
};
⚙️ 应用配置
1. 更新 Expo 配置
更新 app.config.ts:
import { ExpoConfig } from "expo/config";
export default ({ config }: { config: ExpoConfig }) => {
const weworkScheme = process.env.WEWORK_SCHEME || "yourapp";
const corpId = process.env.WEWORK_CORP_ID || "your-corp-id";
const agentId = process.env.WEWORK_AGENT_ID || "your-agent-id";
return {
...config,
scheme: weworkScheme,
plugins: [
// 其他插件...
"./plugins/withWeworkConfig.js"
],
android: {
...config.android,
intentFilters: [
{
action: "VIEW",
category: ["DEFAULT", "BROWSABLE"],
data: [
{
scheme: weworkScheme
}
]
}
]
},
ios: {
...config.ios,
infoPlist: {
CFBundleURLTypes: [
{
CFBundleURLName: "wework-auth",
CFBundleURLSchemes: [weworkScheme]
}
],
LSApplicationQueriesSchemes: ["wxwork"]
}
},
extra: {
...config.extra,
wework: {
corpId,
agentId,
scheme: weworkScheme
}
}
};
};
2. 创建配置插件
创建 plugins/withWeworkConfig.js:
const { withAndroidManifest, withInfoPlist } = require('@expo/config-plugins');
function withWeworkConfig(config) {
// Android 配置
config = withAndroidManifest(config, (config) => {
const manifest = config.modResults;
// 添加企业微信权限
if (!manifest.manifest['uses-permission']) {
manifest.manifest['uses-permission'] = [];
}
manifest.manifest['uses-permission'].push({
$: { 'android:name': 'android.permission.INTERNET' }
});
// 添加 WXEntryActivity
const application = manifest.manifest.application[0];
if (!application.activity) {
application.activity = [];
}
application.activity.push({
$: {
'android:name': 'expo.modules.weworkmodule.WXEntryActivity',
'android:exported': 'true',
'android:launchMode': 'singleTop'
},
'intent-filter': [
{
action: [{ $: { 'android:name': 'android.intent.action.VIEW' } }],
category: [
{ $: { 'android:name': 'android.intent.category.DEFAULT' } },
{ $: { 'android:name': 'android.intent.category.BROWSABLE' } }
],
data: [{ $: { 'android:scheme': config.extra?.wework?.scheme || 'yourapp' } }]
}
]
});
return config;
});
// iOS 配置
config = withInfoPlist(config, (config) => {
const infoPlist = config.modResults;
// 确保 URL Schemes 配置
if (!infoPlist.CFBundleURLTypes) {
infoPlist.CFBundleURLTypes = [];
}
const weworkScheme = config.extra?.wework?.scheme || 'yourapp';
infoPlist.CFBundleURLTypes.push({
CFBundleURLName: 'wework-auth',
CFBundleURLSchemes: [weworkScheme]
});
// 添加查询白名单
if (!infoPlist.LSApplicationQueriesSchemes) {
infoPlist.LSApplicationQueriesSchemes = [];
}
if (!infoPlist.LSApplicationQueriesSchemes.includes('wxwork')) {
infoPlist.LSApplicationQueriesSchemes.push('wxwork');
}
return config;
});
return config;
}
module.exports = withWeworkConfig;
🎬 使用示例
1. 在组件中使用
import React, { useEffect } from 'react';
import { View, Text, TouchableOpacity, Alert } from 'react-native';
import Constants from 'expo-constants';
import { useWework } from '@/modules/wework-module';
export const LoginScreen = () => {
const weworkConfig = Constants.expoConfig?.extra?.wework;
const { isInstalled, isLoading, login, openChat } = useWework(weworkConfig);
useEffect(() => {
if (!isInstalled) {
Alert.alert('提示', '请先安装企业微信客户端');
}
}, [isInstalled]);
const handleWeworkLogin = async () => {
try {
const result = await login();
if (result.code) {
// 使用授权码换取用户信息
console.log('授权成功,授权码:', result.code);
// 调用后端接口换取 access_token 和用户信息
await exchangeCodeForToken(result.code);
}
} catch (error) {
Alert.alert('授权失败', error.message);
}
};
const exchangeCodeForToken = async (code: string) => {
// 调用后端接口
const response = await fetch('/api/wework/oauth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code })
});
const data = await response.json();
// 处理用户信息和 token
};
return (
<View className="flex-1 justify-center items-center p-4">
<Text className="text-2xl font-bold mb-8">登录</Text>
{isInstalled ? (
<TouchableOpacity
onPress={handleWeworkLogin}
disabled={isLoading}
className="bg-blue-500 px-6 py-3 rounded-lg"
>
<Text className="text-white font-semibold">
{isLoading ? '授权中...' : '企业微信登录'}
</Text>
</TouchableOpacity>
) : (
<Text className="text-red-500">请先安装企业微信</Text>
)}
</View>
);
};
2. 后端 OAuth 处理
// 后端接口示例 (Node.js)
app.post('/api/wework/oauth', async (req, res) => {
const { code } = req.body;
try {
// 1. 使用 code 换取 access_token
const tokenResponse = await fetch(
`https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${CORP_ID}&corpsecret=${SECRET}`
);
const { access_token } = await tokenResponse.json();
// 2. 获取用户信息
const userResponse = await fetch(
`https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=${access_token}&code=${code}`
);
const userInfo = await userResponse.json();
// 3. 生成应用 token
const appToken = generateJWT(userInfo);
res.json({
success: true,
token: appToken,
user: userInfo
});
} catch (error) {
res.status(400).json({
success: false,
error: error.message
});
}
});
🚨 常见问题和坑点
1. Android 相关问题
问题:AAR 文件无法识别
# 解决方案:检查 build.gradle 配置
# 确保正确引用 AAR 文件
implementation files('libs/wxwork.aar')
# 如果还是有问题,尝试手动解压 AAR
unzip wxwork.aar -d wxwork/
# 然后引用 classes.jar
implementation files('wxwork/classes.jar')
问题:混淆导致的问题
在 android/app/proguard-rules.pro 中添加:
# 企业微信 SDK
-keep class com.tencent.wework.api.** { *; }
-keep class com.tencent.wework.api.model.** { *; }
-dontwarn com.tencent.wework.api.**
问题:WXEntryActivity 无法接收回调
<!-- 确保在 AndroidManifest.xml 中正确配置 -->
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="你的应用scheme" />
</intent-filter>
</activity>
2. iOS 相关问题
问题:Framework 找不到
# 解决方案:检查 Podspec 配置
s.vendored_frameworks = 'WWKApi.framework'
# 确保 Framework 路径正确
s.framework_search_paths = '$(PODS_TARGET_SRCROOT)'
问题:编译报错 "OBJC_CLASS$_WWKApi"
# 在 Podfile 中添加
pod 'WeworkModule', :path => '../modules/wework-module'
# 如果还是有问题,尝试手动链接
target.build_configurations.each do |config|
config.build_settings['OTHER_LDFLAGS'] ||= ['$(inherited)']
config.build_settings['OTHER_LDFLAGS'] << '-ObjC'
end
问题:URL Scheme 不生效
确保在 Info.plist 中正确配置:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>wework-auth</string>
<key>CFBundleURLSchemes</key>
<array>
<string>你的应用scheme</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>wxwork</string>
</array>
3. JavaScript 层问题
问题:模块找不到
# 确保正确安装开发客户端
npx expo install expo-dev-client
# 重新构建项目
npx expo run:android --clear
npx expo run:ios --clear
问题:深度链接不工作
// 确保正确处理 Linking
import * as Linking from 'expo-linking';
// 检查 URL 格式
const url = await Linking.getInitialURL();
console.log('Initial URL:', url);
// 确保 scheme 匹配
const parsed = Linking.parse(url);
console.log('Parsed URL:', parsed);
4. 网络和权限问题
问题:网络请求失败
<!-- Android 9+ 需要允许 HTTP 请求 -->
<!-- android/app/src/main/res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">qyapi.weixin.qq.com</domain>
</domain-config>
</network-security-config>
问题:企业微信检测不到应用
# 确保应用签名与企业微信后台配置一致
# 获取应用签名
keytool -list -v -keystore your-release-key.keystore
# 配置企业微信后台
# 应用详情 -> 功能设置 -> 网页授权及JS-SDK -> 可信域名
🧪 测试验证
1. 开发环境测试
# 启动开发服务器
yarn start
# 在模拟器中测试
yarn android
yarn ios
# 检查日志
npx react-native log-android
npx react-native log-ios
2. 真机测试
# 构建测试版本
eas build --platform android --profile preview
eas build --platform ios --profile preview
# 安装到真机测试
# 确保设备已安装企业微信
3. 功能测试清单
- 安装检测 - 正确检测企业微信安装状态
- 授权流程 - 完整的授权登录流程
- 回调处理 - 正确处理授权回调
- 错误处理 - 各种异常情况的处理
- 深度链接 - 应用间跳转功能
- 会话跳转 - 跳转到指定企微会话
📚 最佳实践
1. 错误处理
export class WeworkError extends Error {
constructor(
message: string,
public code: string,
public details?: any
) {
super(message);
this.name = 'WeworkError';
}
}
export const handleWeworkError = (error: any): WeworkError => {
if (error.code === 'WEWORK_NOT_INSTALLED') {
return new WeworkError('请先安装企业微信', 'NOT_INSTALLED');
}
if (error.code === 'AUTH_CANCELLED') {
return new WeworkError('用户取消授权', 'USER_CANCELLED');
}
return new WeworkError('未知错误', 'UNKNOWN', error);
};
2. 配置管理
interface WeworkConfig {
corpId: string;
agentId: string;
scheme: string;
secret?: string; // 仅后端使用
}
export const getWeworkConfig = (): WeworkConfig => {
const config = Constants.expoConfig?.extra?.wework;
if (!config?.corpId || !config?.agentId) {
throw new Error('企业微信配置缺失');
}
return config;
};
3. 状态管理
// 使用 Zustand 管理企业微信状态
interface WeworkState {
isInstalled: boolean;
isLoggedIn: boolean;
userInfo: any;
setInstalled: (installed: boolean) => void;
setUserInfo: (user: any) => void;
logout: () => void;
}
export const useWeworkStore = create<WeworkState>((set) => ({
isInstalled: false,
isLoggedIn: false,
userInfo: null,
setInstalled: (installed) => set({ isInstalled: installed }),
setUserInfo: (user) => set({ userInfo: user, isLoggedIn: !!user }),
logout: () => set({ userInfo: null, isLoggedIn: false }),
}));
📝 总结
企业微信 SDK 集成虽然步骤较多,但按照本指南的步骤操作,可以避免大部分常见问题。关键要点:
- 环境配置 - 确保企业微信后台配置正确
- 原生模块 - 正确集成 Android 和 iOS SDK
- 深度链接 - 处理好应用间跳转和回调
- 错误处理 - 完善的异常处理机制
- 测试验证 - 在真机上完整测试功能
完成集成后,您的应用将具备企业微信免密登录、会话跳转等强大功能,大大提升企业用户的使用体验。
💡 提示: 企业微信 SDK 更新较为频繁,建议定期关注官方文档和更新日志,及时升级 SDK 版本。