logo
AI对话
AI写作
AI学术
AI绘画
知识社区

如何在React Native中实现iOS灵动岛功能的详细教程

此对话是使用 海鲸AI 创建的 • 发布时间:2025年06月18日 22:46

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 文件

  1. 打开你的 React Native 项目,导航到 iOS 文件夹
  2. 在 Xcode 中打开 .xcworkspace 文件
  3. 右键点击你的项目名称(通常在左侧导航栏)
  4. 选择 “New File…”
  5. 选择 “Swift File”,点击 “Next”
  6. 命名为 “DynamicIslandManager.swift”,点击 “Create”
  7. 如果提示创建 “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 的文件:

  1. 右键点击你的项目名称
  2. 选择 “New File…”
  3. 选择 “Objective-C File”,点击 “Next”
  4. 命名为 “DynamicIslandManager”,点击 “Create”
  5. 在文件类型选择对话框中选择 “.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 中添加必要配置

  1. 打开 Info.plist 文件
  2. 添加以下键值对:
    • 键: NSSupportsLiveActivities
    • 类型: Boolean
    • 值: YES

步骤 5: 创建 React Native 模块

在你的 React Native 项目中创建一个 JavaScript 文件来与原生模块交互:

  1. 在你的项目根目录下创建 src/nativeModules 文件夹(如果不存在)
  2. 创建 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;

注意事项

  1. 灵动岛功能仅在 iPhone 14 Pro 及更新机型上可用
  2. 需要 iOS 16 或更高版本
  3. 在真机上测试时,应用必须具有适当的权限
  4. 在模拟器上可能无法正常显示灵动岛效果
  5. 如果想要更复杂的灵动岛布局,需要创建 Widget Extension 并使用 SwiftUI 来自定义视图

这个教程提供了基本的灵动岛集成。如果你需要更复杂的功能,可能需要进一步学习 ActivityKit 和 WidgetKit 的相关知识。

重新生成
语音播放
复制回答