react native 如何设置ios灵动岛,我需要写原生代码 然后通过nativemodule 在rn里面调用, 我不太懂swift 所以教程麻烦详细一点,包括如何创建文件 文件放在哪里
复制问题

React Native 与 iOS 灵动岛 (Dynamic Island) 集成教程
要在 React Native 应用中使用 iOS 灵动岛功能,你需要创建原生 Swift 代码,并通过 NativeModule 在 React Native 中调用它。以下是详细步骤:
前提条件
- Xcode 14 或更高版本
- iOS 16 或更高版本的设备(支持灵动岛的 iPhone 14 Pro 或更新机型)
- React Native 项目
步骤 1: 创建原生 Swift 文件
- 打开你的 React Native 项目,导航到 iOS 文件夹
- 在 Xcode 中打开
.xcworkspace
文件 - 右键点击你的项目名称(通常在左侧导航栏)
- 选择 “New File…”
- 选择 “Swift File”,点击 “Next”
- 命名为 “DynamicIslandManager.swift”,点击 “Create”
- 如果提示创建 “Objective-C Bridging Header”,点击 “Create Bridging Header”
步骤 2: 编写 Swift 代码
在 DynamicIslandManager.swift
文件中添加以下代码:
import Foundation
import ActivityKit
@objc(DynamicIslandManager)
class DynamicIslandManager: NSObject {
private var liveActivity: Activity<DynamicIslandAttributes>? = nil
@objc func startDynamicIsland(_ title: String, subtitle: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
// 检查系统是否支持 Live Activities
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
rejecter("error", "Live activities not supported", nil)
return
}
let attributes = DynamicIslandAttributes(name: title)
let state = DynamicIslandAttributes.ContentState(subtitle: subtitle)
do {
liveActivity = try Activity.request(attributes: attributes, contentState: state)
resolver(["id": liveActivity?.id ?? ""])
} catch {
rejecter("error", error.localizedDescription, error)
}
}
@objc func updateDynamicIsland(_ subtitle: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
guard let liveActivity = liveActivity else {
rejecter("error", "No active Dynamic Island to update", nil)
return
}
let state = DynamicIslandAttributes.ContentState(subtitle: subtitle)
Task {
await liveActivity.update(using: state)
resolver(true)
}
}
@objc func endDynamicIsland(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
guard let liveActivity = liveActivity else {
rejecter("error", "No active Dynamic Island to end", nil)
return
}
Task {
await liveActivity.end(dismissalPolicy: .immediate)
resolver(true)
}
self.liveActivity = nil
}
}
// 定义 Dynamic Island 属性
struct DynamicIslandAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var subtitle: String
}
var name: String
}
步骤 3: 创建 Objective-C 桥接文件
创建一个名为 DynamicIslandManager.m
的文件:
- 右键点击你的项目名称
- 选择 “New File…”
- 选择 “Objective-C File”,点击 “Next”
- 命名为 “DynamicIslandManager”,点击 “Create”
- 在文件类型选择对话框中选择 “.m” 文件类型
在 DynamicIslandManager.m
文件中添加以下代码:
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(DynamicIslandManager, NSObject)
RCT_EXTERN_METHOD(startDynamicIsland:(NSString *)title
subtitle:(NSString *)subtitle
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(updateDynamicIsland:(NSString *)subtitle
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(endDynamicIsland:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
+ (BOOL)requiresMainQueueSetup
{
return NO;
}
@end
步骤 4: 在 Info.plist 中添加必要配置
- 打开
Info.plist
文件 - 添加以下键值对:
- 键:
NSSupportsLiveActivities
- 类型: Boolean
- 值: YES
- 键:
步骤 5: 创建 React Native 模块
在你的 React Native 项目中创建一个 JavaScript 文件来与原生模块交互:
- 在你的项目根目录下创建
src/nativeModules
文件夹(如果不存在) - 创建
DynamicIsland.js
文件
在 DynamicIsland.js
中添加以下代码:
import { NativeModules } from 'react-native';
const { DynamicIslandManager } = NativeModules;
export default {
/**
* 启动灵动岛
* @param {string} title - 显示在灵动岛上的主标题
* @param {string} subtitle - 显示在灵动岛上的副标题
* @returns {Promise<Object>} - 包含活动ID的对象
*/
startDynamicIsland: (title, subtitle) => {
return DynamicIslandManager.startDynamicIsland(title, subtitle);
},
/**
* 更新灵动岛内容
* @param {string} subtitle - 更新的副标题内容
* @returns {Promise<boolean>} - 更新是否成功
*/
updateDynamicIsland: (subtitle) => {
return DynamicIslandManager.updateDynamicIsland(subtitle);
},
/**
* 结束灵动岛显示
* @returns {Promise<boolean>} - 结束是否成功
*/
endDynamicIsland: () => {
return DynamicIslandManager.endDynamicIsland();
}
};
步骤 6: 在 React Native 中使用
现在你可以在 React Native 组件中使用这个模块:
import React, { useState } from 'react';
import { View, Button, Text, Platform } from 'react-native';
import DynamicIsland from './src/nativeModules/DynamicIsland';
const App = () => {
const [isActive, setIsActive] = useState(false);
const startActivity = async () => {
if (Platform.OS !== 'ios') return;
try {
await DynamicIsland.startDynamicIsland('我的应用', '正在进行中...');
setIsActive(true);
} catch (error) {
console.error('启动灵动岛失败:', error);
}
};
const updateActivity = async () => {
if (Platform.OS !== 'ios' || !isActive) return;
try {
await DynamicIsland.updateDynamicIsland('更新内容 ' + new Date().toLocaleTimeString());
} catch (error) {
console.error('更新灵动岛失败:', error);
}
};
const endActivity = async () => {
if (Platform.OS !== 'ios' || !isActive) return;
try {
await DynamicIsland.endDynamicIsland();
setIsActive(false);
} catch (error) {
console.error('结束灵动岛失败:', error);
}
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginBottom: 20 }}>
{isActive ? '灵动岛已激活' : '灵动岛未激活'}
</Text>
<Button title="启动灵动岛" onPress={startActivity} disabled={isActive} />
<Button title="更新灵动岛" onPress={updateActivity} disabled={!isActive} />
<Button title="结束灵动岛" onPress={endActivity} disabled={!isActive} />
</View>
);
};
export default App;
注意事项
- 灵动岛功能仅在 iPhone 14 Pro 及更新机型上可用
- 需要 iOS 16 或更高版本
- 在真机上测试时,应用必须具有适当的权限
- 在模拟器上可能无法正常显示灵动岛效果
- 如果想要更复杂的灵动岛布局,需要创建 Widget Extension 并使用 SwiftUI 来自定义视图
这个教程提供了基本的灵动岛集成。如果你需要更复杂的功能,可能需要进一步学习 ActivityKit 和 WidgetKit 的相关知识。
重新生成
语音播放
复制回答