use block::{ConcreteBlock, IntoConcreteBlock};
use objc::{msg_send, sel, sel_impl};
use crate::{
foundation::{NSArray, NSData, NSEnumerator, NSError, NSPredicate, NSString},
object,
objective_c_runtime::{
id,
macros::interface_impl,
nil,
traits::{FromId, PNSObject},
},
utils::to_bool,
};
use super::{
CNChangeHistoryEvent, CNChangeHistoryFetchRequest, CNContact, CNContactFetchRequest,
CNContainer, CNFetchResult, CNGroup, CNSaveRequest,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i64)]
pub enum CNEntityType {
Contacts,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i64)]
pub enum CNAuthorizationStatus {
NotDetermined = 0,
Restricted,
Denied,
Authorized,
}
object! {
unsafe pub struct CNContactStore;
}
#[interface_impl(NSObject)]
impl CNContactStore {
#[method]
pub fn request_access_for_entity_type_completion_handler<F>(
&self,
entity_type: CNEntityType,
completion_handler: F,
) where
F: IntoConcreteBlock<(bool, *mut NSError), Ret = ()> + 'static,
{
let block = ConcreteBlock::new(completion_handler);
let block = block.copy();
unsafe {
msg_send![
self.m_self(),
requestAccessForEntityType: entity_type
completionHandler: block
]
}
}
#[method]
pub fn authorization_status_for_entity_type(
entity_type: CNEntityType,
) -> CNAuthorizationStatus {
unsafe {
msg_send![
Self::m_class(),
authorizationStatusForEntityType: entity_type
]
}
}
#[method]
pub fn enumerate_contacts_with_fetch_request_using_block<F>(
&self,
fetch_request: CNContactFetchRequest,
block: F,
) -> Result<bool, NSError>
where
F: IntoConcreteBlock<(CNContact, *mut bool), Ret = ()> + 'static,
{
let mut error = NSError::m_alloc();
let block = ConcreteBlock::new(block);
let block = block.copy();
unsafe {
let ptr = msg_send![
self.m_self(),
enumerateContactsWithFetchRequest: fetch_request
error: &mut error
usingBlock: block
];
if error.m_self() == nil {
Ok(ptr)
} else {
Err(error)
}
}
}
#[method]
pub fn unified_me_contact_with_keys_to_fetch(
&self,
keys: NSArray<id>,
) -> Result<CNContact, NSError> {
let mut error = NSError::m_alloc();
unsafe {
let result = CNContact::from_id(msg_send![
self.m_self(),
unifiedMeContactWithKeysToFetch: keys
error: &mut error
]);
if error.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn unified_contact_with_identifier_keys_to_fetch(
&self,
identifier: NSString,
keys: NSArray<id>,
) -> Result<CNContact, NSError> {
let mut error = NSError::m_alloc();
unsafe {
let result = CNContact::from_id(msg_send![
self.m_self(),
unifiedContactWithIdentifier: identifier
keysToFetch: keys
error: &mut error
]);
if error.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn unified_contacts_matching_predicate_keys_to_fetch(
&self,
predicate: NSPredicate,
keys: NSArray<id>,
) -> Result<NSArray<CNContact>, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let result = NSArray::from_id(msg_send![
self.m_self(),
unifiedContactsMatchingPredicate: predicate
keysToFetch: keys
error: &mut error
]);
if error.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn enumerator_for_contact_fetch_request(
&self,
fetch_request: CNContactFetchRequest,
) -> Result<CNFetchResult<NSEnumerator<CNContact>>, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let result = CNFetchResult::from_id(msg_send![
self.m_self(),
enumeratorForContactFetchRequest: fetch_request
error: &mut error
]);
if !result.m_self().is_null() {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn default_container_identifier(&self) -> NSString {
unsafe { NSString::from_id(msg_send![self.m_self(), defaultContainerIdentifier]) }
}
#[method]
pub fn groups_matching_predicate(
&self,
predicate: NSPredicate,
) -> Result<NSArray<CNGroup>, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let result = NSArray::from_id(msg_send![
self.m_self(),
groupsMatchingPredicate: predicate
error: &mut error
]);
if error.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn containers_matching_predicate(
&self,
predicate: NSPredicate,
) -> Result<NSArray<CNContainer>, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let result = NSArray::from_id(msg_send![
self.m_self(),
containersMatchingPredicate: predicate
error: &mut error
]);
if error.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[method]
pub fn enumerator_for_change_history_fetch_request(
&self,
request: CNChangeHistoryFetchRequest,
) -> Result<CNFetchResult<NSEnumerator<CNChangeHistoryEvent>>, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let result = CNFetchResult::from_id(msg_send![
self.m_self(),
enumeratorForChangeHistoryFetchRequest: request
error: &mut error
]);
if result.m_self() == nil {
Ok(result)
} else {
Err(error)
}
}
}
#[property]
pub fn current_history_token(&self) -> NSData {
unsafe { NSData::from_id(msg_send![self.m_self(), currentHistoryToken]) }
}
#[method]
pub fn execute_save_request(&self, request: CNSaveRequest) -> Result<bool, NSError> {
unsafe {
let mut error = NSError::m_alloc();
let ptr =
to_bool(msg_send![self.m_self(), executeSaveRequest: request error: &mut error]);
if error.m_self() != nil {
Err(error)
} else {
Ok(ptr)
}
}
}
}
extern "C" {
pub static CNContactStoreDidChangeNotification: *const NSString;
}