1use block::{ConcreteBlock, IntoConcreteBlock};
2use objc::{msg_send, sel, sel_impl};
3
4use crate::{
5 foundation::{NSArray, NSData, NSEnumerator, NSError, NSPredicate, NSString},
6 object,
7 objective_c_runtime::{
8 id,
9 macros::interface_impl,
10 nil,
11 traits::{FromId, PNSObject},
12 },
13 utils::to_bool,
14};
15
16use super::{
17 CNChangeHistoryEvent, CNChangeHistoryFetchRequest, CNContact, CNContactFetchRequest,
18 CNContainer, CNFetchResult, CNGroup, CNSaveRequest,
19};
20
21#[derive(Debug, Copy, Clone, PartialEq, Eq)]
23#[repr(i64)]
24pub enum CNEntityType {
25 Contacts,
27}
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq)]
31#[repr(i64)]
32pub enum CNAuthorizationStatus {
33 NotDetermined = 0,
35 Restricted,
37 Denied,
39 Authorized,
41}
42
43object! {
44 unsafe pub struct CNContactStore;
46}
47
48#[interface_impl(NSObject)]
49impl CNContactStore {
50 #[method]
52 pub fn request_access_for_entity_type_completion_handler<F>(
53 &self,
54 entity_type: CNEntityType,
55 completion_handler: F,
56 ) where
57 F: IntoConcreteBlock<(bool, *mut NSError), Ret = ()> + 'static,
58 {
59 let block = ConcreteBlock::new(completion_handler);
60 let block = block.copy();
61
62 unsafe {
63 msg_send![
64 self.m_self(),
65 requestAccessForEntityType: entity_type
66 completionHandler: block
67 ]
68 }
69 }
70
71 #[method]
73 pub fn authorization_status_for_entity_type(
74 entity_type: CNEntityType,
75 ) -> CNAuthorizationStatus {
76 unsafe {
77 msg_send![
78 Self::m_class(),
79 authorizationStatusForEntityType: entity_type
80 ]
81 }
82 }
83
84 #[method]
89 pub fn enumerate_contacts_with_fetch_request_using_block<F>(
90 &self,
91 fetch_request: CNContactFetchRequest,
92 block: F,
93 ) -> Result<bool, NSError>
94 where
95 F: IntoConcreteBlock<(CNContact, *mut bool), Ret = ()> + 'static,
96 {
97 let mut error = NSError::m_alloc();
98 let block = ConcreteBlock::new(block);
99 let block = block.copy();
100
101 unsafe {
102 let ptr = msg_send![
103 self.m_self(),
104 enumerateContactsWithFetchRequest: fetch_request
105 error: &mut error
106 usingBlock: block
107 ];
108
109 if error.m_self() == nil {
110 Ok(ptr)
111 } else {
112 Err(error)
113 }
114 }
115 }
116
117 #[method]
119 pub fn unified_me_contact_with_keys_to_fetch(
120 &self,
121 keys: NSArray<id>,
122 ) -> Result<CNContact, NSError> {
123 let mut error = NSError::m_alloc();
124
125 unsafe {
126 let result = CNContact::from_id(msg_send![
127 self.m_self(),
128 unifiedMeContactWithKeysToFetch: keys
129 error: &mut error
130 ]);
131
132 if error.m_self() == nil {
133 Ok(result)
134 } else {
135 Err(error)
136 }
137 }
138 }
139
140 #[method]
142 pub fn unified_contact_with_identifier_keys_to_fetch(
143 &self,
144 identifier: NSString,
145 keys: NSArray<id>,
146 ) -> Result<CNContact, NSError> {
147 let mut error = NSError::m_alloc();
148 unsafe {
149 let result = CNContact::from_id(msg_send![
150 self.m_self(),
151 unifiedContactWithIdentifier: identifier
152 keysToFetch: keys
153 error: &mut error
154 ]);
155
156 if error.m_self() == nil {
157 Ok(result)
158 } else {
159 Err(error)
160 }
161 }
162 }
163
164 #[method]
166 pub fn unified_contacts_matching_predicate_keys_to_fetch(
167 &self,
168 predicate: NSPredicate,
169 keys: NSArray<id>,
170 ) -> Result<NSArray<CNContact>, NSError> {
171 unsafe {
172 let mut error = NSError::m_alloc();
173 let result = NSArray::from_id(msg_send![
174 self.m_self(),
175 unifiedContactsMatchingPredicate: predicate
176 keysToFetch: keys
177 error: &mut error
178 ]);
179
180 if error.m_self() == nil {
181 Ok(result)
182 } else {
183 Err(error)
184 }
185 }
186 }
187
188 #[method]
190 pub fn enumerator_for_contact_fetch_request(
191 &self,
192 fetch_request: CNContactFetchRequest,
193 ) -> Result<CNFetchResult<NSEnumerator<CNContact>>, NSError> {
194 unsafe {
195 let mut error = NSError::m_alloc();
196 let result = CNFetchResult::from_id(msg_send![
197 self.m_self(),
198 enumeratorForContactFetchRequest: fetch_request
199 error: &mut error
200 ]);
201
202 if !result.m_self().is_null() {
203 Ok(result)
204 } else {
205 Err(error)
206 }
207 }
208 }
209
210 #[method]
215 pub fn default_container_identifier(&self) -> NSString {
216 unsafe { NSString::from_id(msg_send![self.m_self(), defaultContainerIdentifier]) }
217 }
218
219 #[method]
221 pub fn groups_matching_predicate(
222 &self,
223 predicate: NSPredicate,
224 ) -> Result<NSArray<CNGroup>, NSError> {
225 unsafe {
226 let mut error = NSError::m_alloc();
227
228 let result = NSArray::from_id(msg_send![
229 self.m_self(),
230 groupsMatchingPredicate: predicate
231 error: &mut error
232 ]);
233
234 if error.m_self() == nil {
235 Ok(result)
236 } else {
237 Err(error)
238 }
239 }
240 }
241
242 #[method]
244 pub fn containers_matching_predicate(
245 &self,
246 predicate: NSPredicate,
247 ) -> Result<NSArray<CNContainer>, NSError> {
248 unsafe {
249 let mut error = NSError::m_alloc();
250 let result = NSArray::from_id(msg_send![
251 self.m_self(),
252 containersMatchingPredicate: predicate
253 error: &mut error
254 ]);
255
256 if error.m_self() == nil {
257 Ok(result)
258 } else {
259 Err(error)
260 }
261 }
262 }
263
264 #[method]
269 pub fn enumerator_for_change_history_fetch_request(
270 &self,
271 request: CNChangeHistoryFetchRequest,
272 ) -> Result<CNFetchResult<NSEnumerator<CNChangeHistoryEvent>>, NSError> {
273 unsafe {
274 let mut error = NSError::m_alloc();
275 let result = CNFetchResult::from_id(msg_send![
276 self.m_self(),
277 enumeratorForChangeHistoryFetchRequest: request
278 error: &mut error
279 ]);
280
281 if result.m_self() == nil {
282 Ok(result)
283 } else {
284 Err(error)
285 }
286 }
287 }
288
289 #[property]
291 pub fn current_history_token(&self) -> NSData {
292 unsafe { NSData::from_id(msg_send![self.m_self(), currentHistoryToken]) }
293 }
294
295 #[method]
300 pub fn execute_save_request(&self, request: CNSaveRequest) -> Result<bool, NSError> {
301 unsafe {
302 let mut error = NSError::m_alloc();
303
304 let ptr =
305 to_bool(msg_send![self.m_self(), executeSaveRequest: request error: &mut error]);
306
307 if error.m_self() != nil {
308 Err(error)
309 } else {
310 Ok(ptr)
311 }
312 }
313 }
314}
315
316extern "C" {
317 pub static CNContactStoreDidChangeNotification: *const NSString;
319}