@jincheng_1995/react-native-device-info-plus 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,456 @@
1
+ ---
2
+ inclusion: always
3
+ ---
4
+
5
+ # React Native 插件开发指南
6
+
7
+ 本文档提供 React Native 原生模块/插件开发的完整指南,适用于新架构(Turbo Modules)。
8
+
9
+ ## 项目结构
10
+
11
+ ```
12
+ react-native-xxx-plugin/
13
+ ├── src/ # TypeScript 源代码
14
+ │ ├── index.tsx # 主入口,导出 API
15
+ │ └── NativeXxx.ts # Turbo Module 接口定义
16
+ ├── ios/ # iOS 原生实现
17
+ │ ├── Xxx.h # Objective-C 头文件
18
+ │ ├── Xxx.mm # Objective-C++ 实现
19
+ │ └── Xxx.podspec # CocoaPods 配置
20
+ ├── android/ # Android 原生实现
21
+ │ ├── build.gradle # Gradle 构建配置
22
+ │ └── src/main/
23
+ │ ├── AndroidManifest.xml # 权限声明
24
+ │ └── java/com/xxx/
25
+ │ ├── XxxModule.kt # 主模块实现
26
+ │ └── XxxPackage.kt # 模块注册
27
+ ├── lib/ # 编译输出目录
28
+ ├── example/ # 示例应用
29
+ ├── package.json # npm 配置
30
+ ├── tsconfig.json # TypeScript 配置
31
+ └── tsconfig.build.json # 构建配置
32
+ ```
33
+
34
+ ## 开发步骤
35
+
36
+ ### 1. TypeScript 接口定义
37
+
38
+ 在 `src/NativeXxx.ts` 中定义 Turbo Module 接口:
39
+
40
+ ```typescript
41
+ import type { TurboModule } from 'react-native';
42
+ import { TurboModuleRegistry } from 'react-native';
43
+
44
+ export interface Spec extends TurboModule {
45
+ // 同步方法
46
+ methodName(param: string): void;
47
+
48
+ // 异步方法(返回 Promise)
49
+ asyncMethod(param: number): Promise<string>;
50
+
51
+ // 复杂类型
52
+ getInfo(): Promise<InfoObject>;
53
+ }
54
+
55
+ export default TurboModuleRegistry.getEnforcing<Spec>('ModuleName');
56
+ ```
57
+
58
+ ### 2. TypeScript 实现层
59
+
60
+ 在 `src/index.tsx` 中封装原生模块:
61
+
62
+ ```typescript
63
+ import { NativeEventEmitter } from 'react-native';
64
+ import NativeXxx from './NativeXxx';
65
+
66
+ class XxxModule {
67
+ async asyncMethod(param: number): Promise<string> {
68
+ return NativeXxx.asyncMethod(param);
69
+ }
70
+
71
+ methodName(param: string): void {
72
+ NativeXxx.methodName(param);
73
+ }
74
+ }
75
+
76
+ export default new XxxModule();
77
+ ```
78
+
79
+ ### 3. iOS 原生实现
80
+
81
+ #### 头文件 (Xxx.h)
82
+
83
+ ```objective-c
84
+ #import <React/RCTBridgeModule.h>
85
+ #import <React/RCTEventEmitter.h>
86
+
87
+ #ifdef RCT_NEW_ARCH_ENABLED
88
+ #import "RNXxxSpec.h"
89
+ @interface Xxx : RCTEventEmitter <NativeXxxSpec>
90
+ #else
91
+ @interface Xxx : RCTEventEmitter <RCTBridgeModule>
92
+ #endif
93
+
94
+ @end
95
+ ```
96
+
97
+ #### 实现文件 (Xxx.mm)
98
+
99
+ ```objective-c
100
+ #import "Xxx.h"
101
+
102
+ @implementation Xxx
103
+
104
+ RCT_EXPORT_MODULE()
105
+
106
+ // 同步方法
107
+ RCT_EXPORT_METHOD(methodName:(NSString *)param) {
108
+ // 实现代码
109
+ }
110
+
111
+ // 异步方法
112
+ RCT_EXPORT_METHOD(asyncMethod:(double)param
113
+ resolve:(RCTPromiseResolveBlock)resolve
114
+ reject:(RCTPromiseRejectBlock)reject) {
115
+ // 实现代码
116
+ resolve(@"result");
117
+ }
118
+
119
+ // 新架构支持
120
+ #ifdef RCT_NEW_ARCH_ENABLED
121
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
122
+ (const facebook::react::ObjCTurboModule::InitParams &)params {
123
+ return std::make_shared<facebook::react::NativeXxxSpecJSI>(params);
124
+ }
125
+ #endif
126
+
127
+ @end
128
+ ```
129
+
130
+ #### CocoaPods 配置 (Xxx.podspec)
131
+
132
+ ```ruby
133
+ require "json"
134
+
135
+ package = JSON.parse(File.read(File.join(__dir__, "../package.json")))
136
+
137
+ Pod::Spec.new do |s|
138
+ s.name = "Xxx"
139
+ s.version = package["version"]
140
+ s.summary = package["description"]
141
+ s.homepage = package["homepage"]
142
+ s.license = package["license"]
143
+ s.authors = package["author"]
144
+ s.platforms = { :ios => "13.0" }
145
+ s.source = { :git => package["repository"], :tag => "#{s.version}" }
146
+ s.source_files = "*.{h,m,mm}"
147
+
148
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
149
+ s.compiler_flags = "-DRCT_NEW_ARCH_ENABLED=1"
150
+ s.pod_target_xcconfig = {
151
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
152
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
153
+ }
154
+ s.dependency "React-Codegen"
155
+ s.dependency "RCT-Folly"
156
+ s.dependency "RCTRequired"
157
+ s.dependency "RCTTypeSafety"
158
+ s.dependency "ReactCommon/turbomodule/core"
159
+ end
160
+
161
+ s.dependency "React-Core"
162
+ end
163
+ ```
164
+
165
+ ### 4. Android 原生实现
166
+
167
+ #### 模块实现 (XxxModule.kt)
168
+
169
+ ```kotlin
170
+ package com.xxx
171
+
172
+ import com.facebook.react.bridge.*
173
+
174
+ class XxxModule(reactContext: ReactApplicationContext) :
175
+ ReactContextBaseJavaModule(reactContext) {
176
+
177
+ override fun getName(): String {
178
+ return "Xxx"
179
+ }
180
+
181
+ @ReactMethod
182
+ fun methodName(param: String) {
183
+ // 实现代码
184
+ }
185
+
186
+ @ReactMethod
187
+ fun asyncMethod(param: Double, promise: Promise) {
188
+ try {
189
+ val result = "result"
190
+ promise.resolve(result)
191
+ } catch (e: Exception) {
192
+ promise.reject("ERROR", "Error message", e)
193
+ }
194
+ }
195
+ }
196
+ ```
197
+
198
+ #### 包注册 (XxxPackage.kt)
199
+
200
+ ```kotlin
201
+ package com.xxx
202
+
203
+ import com.facebook.react.ReactPackage
204
+ import com.facebook.react.bridge.NativeModule
205
+ import com.facebook.react.bridge.ReactApplicationContext
206
+ import com.facebook.react.uimanager.ViewManager
207
+
208
+ class XxxPackage : ReactPackage {
209
+ override fun createNativeModules(
210
+ reactContext: ReactApplicationContext
211
+ ): List<NativeModule> {
212
+ return listOf(XxxModule(reactContext))
213
+ }
214
+
215
+ override fun createViewManagers(
216
+ reactContext: ReactApplicationContext
217
+ ): List<ViewManager<*, *>> {
218
+ return emptyList()
219
+ }
220
+ }
221
+ ```
222
+
223
+ #### Gradle 配置 (build.gradle)
224
+
225
+ ```gradle
226
+ buildscript {
227
+ repositories {
228
+ google()
229
+ mavenCentral()
230
+ }
231
+ dependencies {
232
+ classpath "com.android.tools.build:gradle:7.4.2"
233
+ }
234
+ }
235
+
236
+ apply plugin: "com.android.library"
237
+
238
+ def isNewArchitectureEnabled() {
239
+ return project.hasProperty("newArchEnabled") &&
240
+ project.newArchEnabled == "true"
241
+ }
242
+
243
+ android {
244
+ compileSdkVersion 33
245
+ defaultConfig {
246
+ minSdkVersion 21
247
+ targetSdkVersion 33
248
+ }
249
+ }
250
+
251
+ repositories {
252
+ mavenCentral()
253
+ google()
254
+ }
255
+
256
+ dependencies {
257
+ implementation "com.facebook.react:react-native:+"
258
+ }
259
+ ```
260
+
261
+ ### 5. package.json 配置
262
+
263
+ ```json
264
+ {
265
+ "name": "react-native-xxx",
266
+ "version": "1.0.0",
267
+ "description": "描述",
268
+ "main": "lib/commonjs/index",
269
+ "module": "lib/module/index",
270
+ "types": "lib/typescript/index.d.ts",
271
+ "react-native": "src/index",
272
+ "source": "src/index",
273
+ "scripts": {
274
+ "typescript": "tsc --noEmit",
275
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
276
+ "prepare": "bob build"
277
+ },
278
+ "peerDependencies": {
279
+ "react": "*",
280
+ "react-native": "*"
281
+ },
282
+ "devDependencies": {
283
+ "@types/react": "^18.2.0",
284
+ "@types/react-native": "^0.73.0",
285
+ "react": "18.2.0",
286
+ "react-native": "0.73.0",
287
+ "react-native-builder-bob": "^0.23.0",
288
+ "typescript": "^5.3.0"
289
+ },
290
+ "react-native-builder-bob": {
291
+ "source": "src",
292
+ "output": "lib",
293
+ "targets": [
294
+ "commonjs",
295
+ "module",
296
+ ["typescript", { "project": "tsconfig.build.json" }]
297
+ ]
298
+ },
299
+ "codegenConfig": {
300
+ "name": "RNXxxSpec",
301
+ "type": "modules",
302
+ "jsSrcsDir": "src",
303
+ "android": {
304
+ "javaPackageName": "com.xxx"
305
+ }
306
+ }
307
+ }
308
+ ```
309
+
310
+ ## 常用功能实现
311
+
312
+ ### 事件发送(原生 → JS)
313
+
314
+ #### iOS
315
+ ```objective-c
316
+ @interface Xxx : RCTEventEmitter
317
+ @end
318
+
319
+ @implementation Xxx
320
+
321
+ - (NSArray<NSString *> *)supportedEvents {
322
+ return @[@"onEvent"];
323
+ }
324
+
325
+ - (void)sendEvent {
326
+ [self sendEventWithName:@"onEvent" body:@{@"data": @"value"}];
327
+ }
328
+
329
+ @end
330
+ ```
331
+
332
+ #### Android
333
+ ```kotlin
334
+ private fun sendEvent(eventName: String, params: WritableMap) {
335
+ reactApplicationContext
336
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
337
+ .emit(eventName, params)
338
+ }
339
+ ```
340
+
341
+ #### TypeScript
342
+ ```typescript
343
+ const eventEmitter = new NativeEventEmitter(NativeModules.Xxx);
344
+ const subscription = eventEmitter.addListener('onEvent', (data) => {
345
+ console.log(data);
346
+ });
347
+
348
+ // 取消监听
349
+ subscription.remove();
350
+ ```
351
+
352
+ ### 权限处理
353
+
354
+ #### iOS (Info.plist)
355
+ ```xml
356
+ <key>NSCameraUsageDescription</key>
357
+ <string>需要访问相机</string>
358
+ <key>NSLocationWhenInUseUsageDescription</key>
359
+ <string>需要访问位置</string>
360
+ ```
361
+
362
+ #### Android (AndroidManifest.xml)
363
+ ```xml
364
+ <uses-permission android:name="android.permission.CAMERA" />
365
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
366
+ ```
367
+
368
+ ### 线程处理
369
+
370
+ #### iOS - 主线程执行
371
+ ```objective-c
372
+ dispatch_async(dispatch_get_main_queue(), ^{
373
+ // UI 操作
374
+ });
375
+ ```
376
+
377
+ #### Android - 主线程执行
378
+ ```kotlin
379
+ currentActivity?.runOnUiThread {
380
+ // UI 操作
381
+ }
382
+ ```
383
+
384
+ ## 调试技巧
385
+
386
+ ### iOS 调试
387
+ ```bash
388
+ # 查看日志
389
+ npx react-native log-ios
390
+
391
+ # 清理构建
392
+ cd ios && rm -rf Pods && pod install
393
+ ```
394
+
395
+ ### Android 调试
396
+ ```bash
397
+ # 查看日志
398
+ npx react-native log-android
399
+
400
+ # 清理构建
401
+ cd android && ./gradlew clean
402
+ ```
403
+
404
+ ### TypeScript 类型检查
405
+ ```bash
406
+ npm run typescript
407
+ ```
408
+
409
+ ## 常见问题
410
+
411
+ ### 1. 模块未找到
412
+ - iOS: 确保运行了 `pod install`
413
+ - Android: 检查 `MainApplication` 中是否注册了包
414
+ - 重新构建: `npm run prepare`
415
+
416
+ ### 2. 类型错误
417
+ - 确保 `tsconfig.json` 中 `types` 包含 `"react-native"`
418
+ - 运行 `npm install` 安装类型定义
419
+
420
+ ### 3. 新架构不工作
421
+ - 确保 RN 版本 >= 0.68
422
+ - iOS: 在 Podfile 中设置 `ENV['RCT_NEW_ARCH_ENABLED'] = '1'`
423
+ - Android: 在 gradle.properties 中设置 `newArchEnabled=true`
424
+
425
+ ## 发布流程
426
+
427
+ ```bash
428
+ # 1. 构建
429
+ npm run prepare
430
+
431
+ # 2. 测试
432
+ npm run typescript
433
+ npm run lint
434
+
435
+ # 3. 更新版本
436
+ npm version patch # 或 minor, major
437
+
438
+ # 4. 发布
439
+ npm publish
440
+ ```
441
+
442
+ ## 最佳实践
443
+
444
+ 1. **类型安全**: 始终使用 TypeScript 定义接口
445
+ 2. **错误处理**: Promise 方法要正确处理 reject
446
+ 3. **内存管理**: 及时清理监听器和定时器
447
+ 4. **权限检查**: 使用敏感功能前检查权限
448
+ 5. **文档完善**: 提供清晰的 README 和示例代码
449
+ 6. **版本兼容**: 明确支持的 RN 版本范围
450
+
451
+ ## 参考资源
452
+
453
+ - [React Native 新架构文档](https://reactnative.dev/docs/the-new-architecture/landing-page)
454
+ - [Turbo Modules 指南](https://reactnative.dev/docs/the-new-architecture/pillars-turbomodules)
455
+ - [iOS 开发文档](https://developer.apple.com/documentation/)
456
+ - [Android 开发文档](https://developer.android.com/docs)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.