What I want to achieve now is that when the app is not running, upon receiving a notification, it displays an interface similar to CallKit with accept and decline buttons.
Here is part of my code:
@available(iOS 17.4, *) class LiveCommunicationManager: NSObject, ConversationManagerDelegate {
static let shared = LiveCommunicationManager() var isInvalidate:Bool = false var configuration: ConversationManager! override init() { let config = ConversationManager.Configuration( ringtoneName: "notes_of_the_optimistic", iconTemplateImageData: UIImage(named: "AppIcon")?.pngData(), // 图标的 PNG 数据 maximumConversationGroups: 1, // 最大对话组数 maximumConversationsPerConversationGroup: 1, // 每个对话组内最大对话数 includesConversationInRecents: false, // 是否在通话记录中显示 supportsVideo: false, // 是否支持视频 supportedHandleTypes: [.generic,.phoneNumber,.emailAddress] // 支持的通话类型 ) configuration = ConversationManager.init(configuration: config) } func reportIncomingCall(uuid: UUID, callerName: String) { configuration.delegate = self let local = Handle(type: .generic, value: callerName, displayName: callerName) let update = Conversation.Update(localMember: local,members: [local],activeRemoteMembers: [local]) Task{ do { try await configuration.reportNewIncomingConversation(uuid: uuid, update: update) print("成功报告新来电") } catch { print("报告新来电失败: \(error.localizedDescription)") } } } func conversationManager(_ manager: ConversationManager, conversationChanged conversation: Conversation) { print("会话状态改变了") } func conversationManagerDidBegin(_ manager: ConversationManager) { print("会话已经开始了") manager.delegate = self } func conversationManagerDidReset(_ manager: ConversationManager) { print("会话将要清除了") } func conversationManager(_ manager: ConversationManager, perform action: ConversationAction) { print("会话接听了") configuration.invalidate() } func conversationManager(_ manager: ConversationManager, timedOutPerforming action: ConversationAction) { print("会话超时了") } func conversationManager(_ manager: ConversationManager, didActivate audioSession: AVAudioSession) { print("会话激活了") } func conversationManager(_ manager: ConversationManager, didDeactivate audioSession: AVAudioSession) { print("会话死亡了") }
}
在Appdelegate里设置了这些: func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// 在这里处理离线推送通知 completionHandler(.noData) // 返回后台任务完成 if let aps = userInfo["aps"] as? [String: Any], let alert = aps["alert"] as? [String : Any]{ // 静默推送的处理逻辑 if #available(iOS 17.4, *) { let manager = LiveCommunicationManager.shared if manager.isInvalidate { return } if let msgType = userInfo["msgType"] as? Int{ if msgType == 5{ manager.configuration.invalidate() }else{ let callerName = alert["title"] as? String ?? "Fanvil" manager.reportIncomingCall(uuid: UUID(), callerName: callerName) } } } } }
Xcode has been configured with the necessary capabilities, such as Background Fetch, Voice over IP, Background Processing, and Push Notification.
The issue now is that sometimes the code works as expected, allowing the app to wake up when not running and displaying the system interface with accept and decline buttons. However, after a few successful attempts, the app stops waking up, and no notification appears. But when I manually open the app, the didReceiveRemoteNotification method gets triggered.
I’d like to know why this stops working after a few times.