Files
tianrunCRM/Assets/3rd/Contacts/Plugins/iOS/Contacts.mm
2020-07-04 14:41:25 +08:00

350 lines
11 KiB
Plaintext
Executable File

//
// Contacts.m
// ContactsList
//
// Created by Apple on 8/4/14.
// Copyright (c) 2014 DreamMakers. All rights reserved.
//
#import "Contacts.h"
#import <AddressBook/AddressBook.h>
#include<pthread.h>
@implementation Contacts
@end
// Helper method to create C string copy
char* aliessmael_MakeStringCopy (const char* string)
{
if (string == NULL)
return NULL;
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
@interface ContactItem :NSObject
{
@public ABRecordRef person;
@public NSString *name ;
@public ABMultiValueRef phoneNumbersRef;
@public NSMutableArray *phoneNumber;
@public NSMutableArray *phoneNumberType;
@public NSMutableArray *emails;
@public NSData* image;
};
@end
@implementation ContactItem
@end
extern "C" {
CFIndex nPeople;
CFArrayRef allPeople;
NSMutableArray* contactItems;
ABAddressBookRef addressBook;
void contact_log( const char* message)
{
UnitySendMessage("ContactsListMessageReceiver", "Log", message );
}
void contact_error( char* error)
{
UnitySendMessage("ContactsListMessageReceiver", "Error", error );
}
void contact_loadName( ContactItem* c )
{
NSString* firstName = (__bridge NSString *)(ABRecordCopyValue(c->person,kABPersonFirstNameProperty));
NSString* lastName = (__bridge NSString *)(ABRecordCopyValue(c->person, kABPersonLastNameProperty));
NSString* f = ( firstName == NULL)?[[NSString alloc]init]:firstName ;
NSString* s = ( lastName == NULL)?[[NSString alloc]init]:lastName ;
c->name = [NSString stringWithFormat:@"%@ %@",f,s];
//c->name = aliessmael_MakeStringCopy([name UTF8String]);
//return aliessmael_MakeStringCopy([name UTF8String]);
}
void contact_loadPhoneNumbers( ContactItem* c )
{
c->phoneNumbersRef = ABRecordCopyValue(c->person, kABPersonPhoneProperty);
long phonesCount = ABMultiValueGetCount(c->phoneNumbersRef);
c->phoneNumber = [NSMutableArray new];
c->phoneNumberType = [NSMutableArray new];
for (CFIndex i = 0; i < phonesCount ;i++) {
NSString *phoneNumber = (__bridge NSString *) ABMultiValueCopyValueAtIndex(c->phoneNumbersRef, i);
[c->phoneNumber addObject:phoneNumber];
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(c->phoneNumbersRef, i);
NSString* phoneLabel = (__bridge NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
[c->phoneNumberType addObject:phoneLabel];
}
}
void contact_loadEmails( ContactItem* c )
{
c->emails = [NSMutableArray new];
ABMultiValueRef emails = ABRecordCopyValue(c->person, kABPersonEmailProperty);
for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++) {
NSString* email = ( __bridge NSString*)ABMultiValueCopyValueAtIndex(emails, j);
[c->emails addObject:email];
//[email release];
}
CFRelease(emails);
}
void contact_loadPhoto( ContactItem* c )
{
UIImage *img = nil;
c->image = nil;
if (c->person != nil && ABPersonHasImageData(c->person)) {
if ( &ABPersonCopyImageDataWithFormat != nil ) {
NSData * data = (__bridge NSData *)ABPersonCopyImageDataWithFormat(c->person, kABPersonImageFormatThumbnail);
c->image = data;
} else {
NSData * data = (__bridge NSData *)ABPersonCopyImageData(c->person);
c->image = data;
}
//CFRelease( img );
} else {
img= nil;
c->image = nil;
}
}
void contact_writeString( NSOutputStream *oStream, NSString* str )
{
if( str == NULL )
{
short size = 0;
[oStream write:(uint8_t *)&size maxLength:2];
}
else
{
const char* data = [str UTF8String];
short size = strlen( data);
//short size = sizeof(data)/ sizeof(char);
[oStream write:(uint8_t *)&size maxLength:2];
[oStream write:(uint8_t *)data maxLength:size];
}
}
const char* contact_toBytes( ContactItem* c )
{
NSOutputStream *oStream = [[NSOutputStream alloc] initToMemory];
[oStream open];
contact_writeString( oStream, NULL);//native id
contact_writeString( oStream, c->name );
short size = 0;
if( c->image == NULL)
{
[oStream write:(uint8_t *)&size maxLength:2];
}
else
{
size = c->image.length;
[oStream write:(uint8_t *)&size maxLength:2];
uint8_t * data = (uint8_t *)[c->image bytes];
[oStream write: data maxLength:size];
}
if( c->phoneNumber == NULL)
{
size = 0;
[oStream write:(uint8_t *)&size maxLength:2];
}
else
{
size = c->phoneNumber.count;
[oStream write:(uint8_t *)&size maxLength:2];
for (int i = 0; i < size; i++)
{
NSString* text1 = [c->phoneNumber objectAtIndex:i];
contact_writeString( oStream, text1 );
NSString* text2 = [c->phoneNumberType objectAtIndex:i];
contact_writeString( oStream, text2 );
}
}
if( c->emails == NULL)
{
size = 0;
[oStream write:(uint8_t *)&size maxLength:2];
}
else
{
size = c->emails.count;
[oStream write:(uint8_t *)&size maxLength:2];
for (int i = 0; i < size; i++)
{
NSString* text = [c->emails objectAtIndex:i];
contact_writeString( oStream, text );
contact_writeString( oStream, NULL );
}
}
size = 0;
[oStream write:(uint8_t *)&size maxLength:2];
NSData *contents = [oStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
[oStream close];
NSString* str = [contents base64Encoding];
return [str UTF8String];
}
char* getContact( int index )
{
//NSString* d = [NSString stringWithFormat:@"Get contact of index : %d", index];
//contact_log([d UTF8String]);
ContactItem* c = [contactItems objectAtIndex:index];
const char* data = contact_toBytes(c);
return aliessmael_MakeStringCopy(data) ;
}
void* contact_load_thread( void *arg)
{
//ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByFirstName);
nPeople = ABAddressBookGetPersonCount( addressBook );
// NSLog( @"error %@" , *error );
// NSLog( @"cont %ld" , nPeople );
contactItems = [NSMutableArray new];
for ( int i = 0; i < nPeople; i++ )
{
ContactItem* c = [[ContactItem alloc]init];
c->person = CFArrayGetValueAtIndex( allPeople, i );
if( c->person == nil)
{
NSLog( @"contact %d is empty" , i );
continue;
}
contact_loadName( c );
contact_loadPhoneNumbers( c);
contact_loadEmails( c );
contact_loadPhoto( c );
[contactItems addObject:c];
NSString *idStr = [NSString stringWithFormat:@"%d",i];
const char* _idStr = [idStr UTF8String] ;
//contact_log( _idStr);
UnitySendMessage("ContactsListMessageReceiver", "OnContactReady", _idStr);
}
UnitySendMessage("ContactsListMessageReceiver", "OnInitializeDone","");
CFRelease(addressBook);
CFRelease(allPeople);
addressBook = NULL;
}
pthread_t thread = NULL;
void contact_listContacts()
{
pthread_create(&(thread), NULL, &contact_load_thread, NULL);
}
void loadIOSContacts()
{
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusDenied) {
// if you got here, user had previously denied/revoked permission for your
// app to access the contacts, and all you can do is handle this gracefully,
// perhaps telling the user that they have to go to settings to grant access
// to contacts
NSLog(@"permissin issu");
[[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
UnitySendMessage("ContactsListMessageReceiver", "OnInitializeFail","kABAuthorizationStatusDenied");
return;
}
CFErrorRef *error = NULL;
addressBook = ABAddressBookCreateWithOptions(NULL, error );
if (error) {
NSLog(@"error: %@", CFBridgingRelease(error));
if (addressBook)
CFRelease(addressBook);
UnitySendMessage("ContactsListMessageReceiver", "OnInitializeFail","Can not create addressbook");
return;
}
if (status == kABAuthorizationStatusNotDetermined)
{
// present the user the UI that requests permission to contacts ...
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
// if they gave you permission, then just carry on
contact_listContacts();
}
else
{
// however, if they didn't give you permission, handle it gracefully, for example...
dispatch_async(dispatch_get_main_queue(), ^{
// BTW, this is not on the main thread, so dispatch UI updates back to the main queue
[[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
});
UnitySendMessage("ContactsListMessageReceiver", "OnInitializeFail","kABAuthorizationStatusNotDetermined");
}
//CFRelease(addressBook);
});
}
else if( status == kABAuthorizationStatusAuthorized )
{
contact_listContacts();
}
else
{
UnitySendMessage("ContactsListMessageReceiver", "OnInitializeFail","unknown issue");
}
}
}