如何在didReceiveRemoteNotification中展示视图并传递推送数据?
接收静默推送时展示自定义视图并传递推送数据
我需要在App接收静默推送通知时,展示一个自定义视图,并将推送携带的数据传递给该视图。目前已完成推送数据的解析与存储逻辑,现有代码如下:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { printLog("Did Receive Remote Notification") printLog(userInfo) do { let jsonResult = try JSONSerialization.data(withJSONObject: userInfo) let push = try JSONDecoder().decode(RequestPushModel.self, from: jsonResult) let single = RequestBearerCustomer(type: "\(push.type)", transport_id: "\(push.transport_id)", shortened_origin_address: "\(push.shortened_origin_address)", origin_lat: "\(push.origin_lat)", origin_lng: "\(push.origin_lng)", time: "\(push.time)", price: "\(push.price)", expire_time: "\(push.expire_time)") if Constants.requestBearerCustomer.count > 0 { Constants.requestBearerCustomer.insert(single, at: Constants.requestBearerCustomer.count - 1) } else { Constants.requestBearerCustomer.insert(single, at: 0) } printLog(single) printLog(Constants.requestBearerCustomer[0]) } catch { printLog(error) } }
实现步骤
1. 确认静默推送配置有效性
静默推送的payload必须包含content-available: 1,且不能包含alert、sound等会触发系统通知栏的字段。同时需在App的Capabilities中开启Background Modes下的Remote notifications选项,确保App能在后台接收推送并被唤醒。
2. 修改推送回调,添加视图触发逻辑
在原回调中加入主线程执行的视图展示逻辑,并正确调用completionHandler(这对后台推送的后续处理至关重要):
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { printLog("Did Receive Remote Notification") printLog(userInfo) do { let jsonResult = try JSONSerialization.data(withJSONObject: userInfo) let push = try JSONDecoder().decode(RequestPushModel.self, from: jsonResult) let single = RequestBearerCustomer(type: "\(push.type)", transport_id: "\(push.transport_id)", shortened_origin_address: "\(push.shortened_origin_address)", origin_lat: "\(push.origin_lat)", origin_lng: "\(push.origin_lng)", time: "\(push.time)", price: "\(push.price)", expire_time: "\(push.expire_time)") // 更新本地数据存储 if Constants.requestBearerCustomer.count > 0 { Constants.requestBearerCustomer.insert(single, at: Constants.requestBearerCustomer.count - 1) } else { Constants.requestBearerCustomer.insert(single, at: 0) } // 主线程触发视图展示,避免UI操作异常 DispatchQueue.main.async { self.showCustomPushView(with: push) } // 根据处理结果返回对应状态 completionHandler(.newData) } catch { printLog(error) completionHandler(.failed) } }
3. 实现自定义视图展示方法
编写专门的方法来创建并展示自定义视图,适配App前台/后台唤醒后的窗口状态:
private func showCustomPushView(with pushData: RequestPushModel) { // 实例化自定义视图,传入推送数据 let customPushView = CustomPushNotificationView() customPushView.pushData = pushData // 假设视图类有接收数据的属性 customPushView.frame = UIScreen.main.bounds // 获取当前活跃的主窗口 guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return } // 添加视图到窗口并添加淡入动画 keyWindow.addSubview(customPushView) customPushView.alpha = 0 UIView.animate(withDuration: 0.3) { customPushView.alpha = 1 } }
4. 后台唤醒场景注意事项
当App从后台被静默推送唤醒时,UIApplication.shared.windows可能需要延迟获取(比如等待App完成启动流程),可根据实际情况添加短暂延迟或监听UIApplication.didBecomeActiveNotification通知,确保视图能正常添加到窗口。
内容的提问来源于stack exchange,提问作者mohammadgdz
相关产品推荐
相关产品推荐

