rust_macios/user_notifications/
un_user_notification_center_delegate.rs1#![allow(trivial_casts)]
2
3use std::sync::Once;
4
5use block::{ConcreteBlock, IntoConcreteBlock};
6use objc::{
7 declare::ClassDecl,
8 msg_send,
9 runtime::{Class, Object, Sel},
10 sel, sel_impl, Encode,
11};
12
13use crate::objective_c_runtime::{class, id, traits::PNSObject};
14
15use super::{
16 UNNotification, UNNotificationResponse, UNUserNotificationCenter,
17 UNUSER_NOTIFICATION_CENTER_PTR,
18};
19
20#[repr(u64)]
21#[derive(Debug)]
22pub enum UNNotificationPresentationOptions {
24 None = 0,
26 Badge = (1 << 0),
28 Sound = (1 << 1),
30 #[deprecated = "Use 'List | Banner' instead."]
32 Alert = (1 << 2),
33 List = (1 << 3),
35 Banner = (1 << 4),
37}
38
39pub trait PUNUserNotificationCenterDelegate: PNSObject {
41 fn user_notification_center_did_receive_notification_response_with_completion_handler<F>(
46 &mut self,
47 center: &UNUserNotificationCenter,
48 response: &UNNotificationResponse,
49 completion_handler: F,
50 ) where
51 F: IntoConcreteBlock<(), Ret = ()> + 'static,
52 {
53 let block = ConcreteBlock::new(completion_handler);
54 let block = block.copy();
55
56 unsafe {
57 msg_send![self.m_self(), userNotificationCenter:center.m_self() didReceiveNotificationResponse:response.m_self() withCompletionHandler: block]
58 }
59 }
60
61 fn user_notification_center_will_present_notification_with_completion_handler<F>(
66 &mut self,
67 center: &UNUserNotificationCenter,
68 notification: &UNNotification,
69 completion_handler: F,
70 ) where
71 F: IntoConcreteBlock<(UNNotificationPresentationOptions,), Ret = ()> + 'static,
72 {
73 let block = ConcreteBlock::new(completion_handler);
74 let block = block.copy();
75
76 unsafe {
77 msg_send![self.m_self(), userNotificationCenter:center.m_self() willPresentNotification:notification.m_self() withCompletionHandler: block]
78 }
79 }
80
81 fn user_notification_center_open_settings_for_notification(
86 &mut self,
87 center: &UNUserNotificationCenter,
88 notification: &UNNotification,
89 ) {
90 unsafe {
91 msg_send![self.m_self(), userNotificationCenter: center.m_self() openSettingsForNotification: notification.m_self()]
92 }
93 }
94}
95
96fn user_notification_center<T>(this: &mut Object) -> &mut T {
99 unsafe {
100 let app_ptr: usize = *this.get_ivar(UNUSER_NOTIFICATION_CENTER_PTR);
101 let app = app_ptr as *mut T;
102 &mut *app
103 }
104}
105
106extern "C" fn user_notification_center_did_receive_notification_response_with_completion_handler<
107 T: PUNUserNotificationCenterDelegate,
108 F: Fn() + Send + Sync + 'static,
109>(
110 this: &mut Object,
111 _: Sel,
112 _: id,
113 center: UNUserNotificationCenter,
114 response: UNNotificationResponse,
115 completion_handler: F,
116) {
117 user_notification_center::<T>(this)
118 .user_notification_center_did_receive_notification_response_with_completion_handler(
119 ¢er,
120 &response,
121 completion_handler,
122 )
123}
124
125extern "C" fn user_notification_center_will_present_notification_with_completion_handler<
126 T: PUNUserNotificationCenterDelegate,
127 F: Fn(UNNotificationPresentationOptions) + Send + Sync + 'static,
128>(
129 this: &mut Object,
130 _: Sel,
131 _: id,
132 center: UNUserNotificationCenter,
133 notification: UNNotification,
134 completion_handler: F,
135) {
136 user_notification_center::<T>(this)
137 .user_notification_center_will_present_notification_with_completion_handler(
138 ¢er,
139 ¬ification,
140 completion_handler,
141 )
142}
143
144extern "C" fn user_notification_center_open_settings_for_notification<
145 T: PUNUserNotificationCenterDelegate,
146>(
147 this: &mut Object,
148 _: Sel,
149 _: id,
150 center: UNUserNotificationCenter,
151 notification: UNNotification,
152) {
153 user_notification_center::<T>(this)
154 .user_notification_center_open_settings_for_notification(¢er, ¬ification)
155}
156
157pub fn register_user_notification_center_delegate_class<
160 T: PUNUserNotificationCenterDelegate + PUNUserNotificationCenterDelegate,
161 F1: Fn() + Send + Sync + 'static + Encode,
162 F2: Fn(UNNotificationPresentationOptions) + Send + Sync + 'static + Encode,
163>() -> *const Class {
164 static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
165 static INIT: Once = Once::new();
166
167 INIT.call_once(|| unsafe {
168 let superclass = class!(NSObject);
169 let mut decl = ClassDecl::new("RSTUNUserNotificationCenterDelegate", superclass).unwrap();
170
171 decl.add_ivar::<usize>(UNUSER_NOTIFICATION_CENTER_PTR);
172
173 decl.add_method(
174 sel!(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:),
175 user_notification_center_did_receive_notification_response_with_completion_handler::<
176 T,
177 F1,
178 > as extern "C" fn(&mut Object, _, _, _, _, _),
179 );
180
181 decl.add_method(
182 sel!(userNotificationCenter:willPresentNotification:withCompletionHandler:),
183 user_notification_center_will_present_notification_with_completion_handler::<T, F2>
184 as extern "C" fn(&mut Object, _, _, _, _, _),
185 );
186
187 decl.add_method(
188 sel!(userNotificationCenter:openSettingsForNotification:),
189 user_notification_center_open_settings_for_notification::<T>
190 as extern "C" fn(&mut Object, _, _, _, _),
191 );
192
193 DELEGATE_CLASS = decl.register();
194 });
195
196 unsafe { DELEGATE_CLASS }
197}