Flutter中如何实现UNNotificationServiceExtension、UNNotificationContentExtension

最新在做Flutter重构APP项目,居然被UNNotificationServiceExtension给困扰了很久,所以在这里记录下整个历程。

UNNotificationServiceExtension的作用相信有iOS基础的有所了解,不了解可以自行去查找资料。

一、添加UNNotificationServiceExtension

使用xcode打开iOS项目;

找到Xcode->File->New->Target


查找UNNotificationServiceExtension



这里填基本信息,记住Team悬着要和主工程一致

添加完成后flutter运行工程,恭喜你开始入坑了,这时候程序会开始报错构建依赖循环(Build Cycle)

具体来说,你的主 Target Runner 和 Notification Service Extension 之间出现了互相依赖或重复拷贝的问题,尤其是在使用 CocoaPods 的情况下

error: Cycle inside Runner; building could produce unreliable results.

Cycle details:

→ Target 'Runner' has copy command from '/Users/***/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/NotificationServiceExtension.appex' to '/Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/Runner.app/PlugIns/NotificationServiceExtension.appex'

○ That command depends on command in Target 'Runner': script phase “[CP] Copy Pods Resources”

○ That command depends on command in Target 'Runner': script phase “[CP] Embed Pods Frameworks”

○ That command depends on command in Target 'Runner': script phase “Thin Binary”

○ Target 'Runner' has process command with output '/Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/Runner.app/Info.plist'

○ Target 'Runner' has copy command from '/Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/NotificationServiceExtension.appex' to '/Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/Runner.app/PlugIns/NotificationServiceExtension.appex'

command: P0:target-Runner-18c1723432283e0cc55f10a6dcfd9e0288a783a885d8b0b3beb2e9f90bde3f49-:Debug:Copy /Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/Runner.app/PlugIns/NotificationServiceExtension.appex /Users/*/Library/Developer/Xcode/DerivedData/Runner-eyxlmdorwasgznftaxwedyqcrssk/Build/Products/Debug-iphoneos/NotificationServiceExtension.appex

1、这时候我们要检查 Target Dependencies

打开 ios/Runner.xcworkspace

选中 Runner 项目 → 选择 Runner Target

进入 General → Frameworks, Libraries, and Embedded Content

确保 NotificationServiceExtension.appex 没有出现在这里

进入 Build Phases → Target Dependencies

删除任何对 NotificationServiceExtension 的依赖(Extension 不应作为主 App 的 Target Dependency)



这时候你的项目中基本都有这个**.appex,需要给他删除

2、检查 Podfile 配置(关键!)

target 'Runner' do

 use_frameworks!

 flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 

end 

target 'NotificationServiceExtension' do 

use_frameworks! 

# ❌ 错误:不要在这里调用 flutter_install_all_ios_pods # ❌ 也不要引入主 App 的 Pods(如 Firebase/Messaging)

 end

3、检查 Build Phases 是否重复

Runner Target → Build Phases中:

确保只有一个 "Embed App Extensions" 或 Copy Files (Destination: PlugIns) 包含你的 .appex

删除任何手动添加的、重复的拷贝操作


注意:我当前使用的是xcode16,添加了PlugIns后General中会自动添加***.appex,导致第1步的操作被重置,陷入死循环;不知道这是不是xcode的bug。

如果不添加PlugIns,项目运行不会报错,但是也不会走UNNotificationServiceExtension!!!

这里额外提一点这里要求发送消息是

{ "aps": 

    "mutable-content": 1} //这里不为1时是不会走消息扩展的

}


于是我使用新得方案来解决这个问题

二、使用脚本


首先添加一个New Run Script Phase 并命名为Manually Embed Notification Extension

添加以下脚本,脚本中EXTENSION_NAME对应您的.appex的名称

#!/bin/sh

set-e

EXTENSION_NAME="****"

BUILD_PRODUCTS_PATH="${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}"

SOURCE_APP_EXTENSION="${BUILD_PRODUCTS_PATH}/${EXTENSION_NAME}.appex"

PLUGINS_DIR="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/PlugIns"

DEST_APP_EXTENSION="${PLUGINS_DIR}/${EXTENSION_NAME}.appex"

echo "🔍 Looking for extension at:${SOURCE_APP_EXTENSION}"

if[ ! -d"${SOURCE_APP_EXTENSION}"];then

    echo "❌ ERROR:${EXTENSION_NAME}.appex not found!"

    echo "👉 Make sure 'NotificationServiceExtension' is added as a Target Dependency of 'Runner'."

    echo "👉 Also ensure the extension builds successfully on its own."

    exit1

fi

mkdir -p"${PLUGINS_DIR}"

rm -rf"${DEST_APP_EXTENSION}"

cp -r"${SOURCE_APP_EXTENSION}""${DEST_APP_EXTENSION}"

echo "✅ Successfully embedded${EXTENSION_NAME}.appex"

 pod install 更新你的cocoapod

一定要保证Manually Embed Notification Extension在Pods Resources 后面;要不然运行会报错的


到这里就可以去验证你的UNNotificationServiceExtension是否起效了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容