最新在做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是否起效了。