add a contact to a group using Contacts framework - ios

I created a group using contacts group, and then I want to add a contact to the group.
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:#[[[NSUserDefaults standardUserDefaults]objectForKey:#"groupIDentifier"]]];
NSArray *groups = [store groupsMatchingPredicate:predicate error:&saveError];
CNMutableContact *contact = [[CNMutableContact alloc] init];
contact.familyName = #"Doe";
contact.givenName = #"John";
CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:[CNPhoneNumber phoneNumberWithStringValue:#"312-555-1212"]];
contact.phoneNumbers = #[homePhone];
CNSaveRequest *request = [CNSaveRequest new];
CNGroup *group = [groups firstObject];
[request addContact:contact toContainerWithIdentifier:group.identifier];
if (![store executeSaveRequest:request error:&saveError]) {
NSLog(#"error = %#", saveError);
}
The error is:
error = Error Domain=CNErrorDomain Code=200 "Updated Record Does Not
Exist" UserInfo={CNInvalidRecordIdentifiers=(
"45FFBB0D-C74B-4A14-8293-9099EA7DEF81:ABGroup" ), NSLocalizedDescription=Updated Record Does Not Exist,
NSLocalizedFailureReason=The save request failed because it updates a
record that does not exist or has already been deleted.}
I also tried using:
[request addMember:contact toGroup:[groups firstObject]];
and this case, the error is:
error = Error Domain=CNErrorDomain Code=200 "Updated Record Does Not Exist" UserInfo={CNInvalidRecords=(
"<CNContact: 0x7f8ce97aa640: identifier=7CC6BC1D-1B23-48DA-8282-06115F542A97:ABPerson, givenName=John, familyName=Doe, organizationName=, phoneNumbers=(\n \"<CNLabeledValue: 0x600001873cc0: identifier=68277209-3AE4-40AF-9EEA-DF0E1D01883C, label=_$!<Home>!$_, value=<CNPhoneNumber: 0x600000433300: stringValue=312-555-1212, initialCountryCode=(null)>>\"\n), emailAddresses=(\n), postalAddresses=(\n)>" ), NSLocalizedFailureReason=The save request failed because it updates a record that does not exist or has already been deleted., NSLocalizedDescription=Updated Record Does Not Exist}

The crazy thing I found is: I need to call both addMember and addContact, to actually make the contact add to the group.
CNGroup *group = [groups firstObject];
[request addMember:contact toGroup:group];
[request addContact:contact toContainerWithIdentifier:nil];
if (![store executeSaveRequest:request error:&saveError]) {
NSLog(#"error = %#", saveError);
}
Response from the Apple Support:
You must save the contact, and group, separately. Then check to see if they exist, before the contact can be added to that group. Otherwise, you will receive the same error you are seeing in the output.
Create the group
Execute the save of the contact
Check if the Contact and the Group both exist
Add contact to group using addMember
This actually serves the purpose, but I have no clue why I have to actually make the two types of requests.

Related

"The user is blocked from live streaming." (Domain=com.google.GTLRErrorObjectDomain Code=403)

When I'm trying to perform request for inserting of a broadcast I receive error:
Error Domain=com.google.GTLRErrorObjectDomain Code=403 "The user is blocked from live streaming."
UserInfo={GTLRStructuredError=GTLRErrorObject 0x28027ad30: {code:403
errors:[1] message:"The user is blocked from live streaming."},
NSLocalizedDescription=The user is blocked from live streaming.}
I have started receiving this error today. Before, everything has been working fine. I have tested on several accounts and had not any luck.
Code:
GTLRYouTube_LiveBroadcastSnippet *broadcastSnippet= [[GTLRYouTube_LiveBroadcastSnippet alloc] init];
[broadcastSnippet setTitle:title];
[broadcastSnippet setScheduledStartTime:[GTLRDateTime dateTimeWithDate:self.beginOfStream]]; // current date + 1 minute.
[broadcastSnippet setScheduledEndTime:[GTLRDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:80000]]];
GTLRYouTube_LiveBroadcastStatus *status = [[GTLRYouTube_LiveBroadcastStatus alloc] init];
[status setPrivacyStatus:[StreamSettings youtubeStringForPrivacyStatus:[privacyStatus intValue]]];
GTLRYouTube_LiveBroadcastContentDetails *details = [self streamDetailsWith:latency];
GTLRYouTube_LiveBroadcast *broadcast = [[GTLRYouTube_LiveBroadcast alloc] init];
[broadcast setKind:#"youtube#liveBroadcast"];
[broadcast setSnippet:broadcastSnippet];
[broadcast setStatus:status];
GTLRYouTubeQuery_LiveBroadcastsInsert *query = [GTLRYouTubeQuery_LiveBroadcastsInsert queryWithObject:broadcast
part:#"id, snippet, contentDetails,status"];
GTLRYouTubeService *service = self.youTubeService;
__strong id <YouTubeHelperDelegate> strongDelegate = self.delegate;
[service executeQuery:query completionHandler:^(GTLRServiceTicket *ticket,
GTLRYouTube_LiveBroadcast *returnedBrocast,
NSError *error) {
if (error) {
NSLog(#"%#", error); //Here is place I got an error
}
}];
If the logged in user does not have more than 1000 subscribers he can't go live using a mobile app, as mentioned in link:
https://support.google.com/youtube/answer/2853834?hl=en

Saving an image as Contact Picture, and displaying it while incoming call

Requirement: I am saving some contacts into the user's iPhone along with a picture (dimensions same as the device). I want this picture to be displayed ON FULLSCREEN whenever the contact calls on that device.
Noticed Example: Truecaller iOS app shows as Red image when the caller is Identified as Spam
Code: This is code I have used to save the contacts data. I am using Contacts.framework
CNMutableContact *newContact = [CNMutableContact new];
newContact.imageData = UIImagePNGRepresentation([UIImage imageNamed:#"blue_bg.png"]);
newContact.contactType = CNContactTypePerson;
newContact.givenName = user.firstName;
newContact.middleName = user.middleName;
newContact.familyName = user.lastName;
NSArray *numbers = [[NSArray alloc] initWithArray:#[[CNLabeledValue labeledValueWithLabel:#"Main" value:[CNPhoneNumber phoneNumberWithStringValue:user.mobileNumber.stringValue]]]];
newContact.phoneNumbers = numbers;
CNContactStore *store = [CNContactStore new];
CNSaveRequest *saveReq = [CNSaveRequest new];
[saveReq addContact:newContact toContainerWithIdentifier:nil];
NSError *error = nil;
[store executeSaveRequest:saveReq error:&error];
if (error) {
NSLog(#"Contact Save ERROR: %#", error.localizedDescription);
}
Current Scenario: I am getting this image in the iOS Contacts App but its not displayed when that user calls on the iPhone. How does Truecaller do it? What am I missing here?
If the image shows up in the Contacts App it should show up when you're getting called by that person.

CKQueryOperation got error "No operations present in request" randomly

I'm trying to fetch some records from Cloud Server w/ the code snippet below. It returns records w/o any error in most times:
CKQuery * query = [[CKQuery alloc] initWithRecordType:#"MyTable"
predicate:[NSPredicate predicateWithFormat:#"accountID = 1"]];
CKQueryOperation * recordFetchOperation = [[CKQueryOperation alloc] initWithQuery:query];
recordFetchOperation.database = [[CKContainer defaultContainer] privateCloudDatabase];
recordFetchOperation.recordFetchedBlock = ^(CKRecord *record) {
// get records succeed some times
};
recordFetchOperation.queryCompletionBlock = ^(CKQueryCursor *cursor, NSError *operationError) {
if (operationError) [self _handleError:operationError];
};
... // some other operations
NSOperationQueue * queue = [[NSOperationQueue alloc] init];
[queue addOperations:#[recordFetchOperation, ...]
waitUntilFinished:NO];
But sometimes, it returns error:
{
NSDebugDescription = "CKInternalErrorDomain: 1009";
NSLocalizedDescription = "No operations present in request";
NSUnderlyingError = "Error Domain=CKInternalErrorDomain Code=1009 \"No operations present in request\" UserInfo={NSLocalizedDescription=No operations present in request}";
}
I've checked the error code, it's CKErrorInvalidArguments, which as doc said
Bad client request (bad record graph, malformed predicate)
I've no idea how this error comes and how to handle this error, unlike CKErrorNetworkUnavailable error, it does not have CKErrorRetryAfterKey value in error.userInfo for me to send the request after a time interval.
Btw, when I got this error, all my operations will have this error w/o any record returned.

iOS: Error deleting contacts from Address book: [CNDataMapperContactStore executeSaveRequest:error:]

I'm trying to implement a deletion of contacts in the address book but I'm getting the following errors.
Here is my implementation:
CNMutableContact *contact = [[cnContacts objectAtIndex:i] copy];
[cnContacts removeObjectAtIndex:i];
CNSaveRequest *request = [[CNSaveRequest alloc] init];
[request deleteContact:contact];
NSError *error;
if (![self.ContactStore executeSaveRequest:request error:&error]) {
if (error)
{
NSLog(#"error = %#", error.description);
}
}
On this line:
if (![self.ContactStore executeSaveRequest:request error:&error]) {
I'm getting this error in the console:
-[CNContact setSnapshot:]: unrecognized selector sent to instance 0x145de3940
Also this errors are showing:
Contacts`-[CNDataMapperContactStore executeSaveRequest:error:]:
libdispatch.dylib`_dispatch_mgr_thread:
Any of you knows why of this errors or what I'm doing wrong in my implementation.
I don't know this API, but looking around I see that:
[request deleteContact:contact];
requires a CNMutableContact object and you have made it immutable by using copy:
CNMutableContact *contact = [[cnContacts objectAtIndex:i] copy];
// contact is actually a CNContact object
You want mutableCopy, however I don't see a need to create a copy at all, assuming cnContacts contains CNMutableContact instances, as removing it from the array will not destroy the object as you still have a reference to it locally.
I can only assume snapshot is private property of CNMutableContact which is not available on CNContact, and hence the unrecognized selector exception (I see nothing about this property in the class reference).

create new group with contacts framework, CNErrorDomain Code = 2

i try to create and save a group with the Contacts Framework.
First the user authorize the App for contacts access.
A viewcontroller is presented and with a + button user shows an alertview with textfield.
The user types the group name he wants and click to button of the alertview (save).
This is the code for saving the new group. The group name is available but it is not possible to save this group anyway:
CNContactStore *contactStore = [CNContactStore new];
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError *error){
if (granted) {
CNMutableGroup *newGroup = [CNMutableGroup new];
CNSaveRequest *saveRequest = [CNSaveRequest new];
[newGroup setName:groupName];
//when saving to container with identifier nil, we get this error:
//Error Domain=CNErrorDomain Code=2 "(null)" UserInfo={CNInvalidRecords=(
//"<CNMutableGroup: 0x10a059f20: identifier=2F4981B9-8A47-45A4-8841-1FA5A09584A4:ABGroup, name=gghh>"
[saveRequest addGroup:newGroup toContainerWithIdentifier:nil];
[contactStore executeSaveRequest:saveRequest error:&error];
if (error){
//error saving group
//NSLog(#"error message: %#",error);
} else {
//if no errors, reload tableview
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}
}];
Error Domain=CNErrorDomain Code=2 "(null)" UserInfo={CNInvalidRecords=(
"<CNMutableGroup: 0x14fb3e5e0: identifier=8E490585-1223-407E-B353-0D25609B05AB:ABGroup, name=jddjd>"
)}
The next strange thing is: why is the save request trying to save this group
with identifier :ABGroup at the end?
The Error contains a info about CNInvalidRecords.
I am only using the Contacts Framework.
Why is this happening?
Any solutions for that?
It worked fine for me, with essentially the same code.
CNMutableGroup *newGroup = [CNMutableGroup new];
CNSaveRequest *saveRequest = [CNSaveRequest new];
[newGroup setName:self.groupName];
[saveRequest addGroup:newGroup toContainerWithIdentifier:nil];
[contactStore executeSaveRequest:saveRequest error:&error];
And created a new group

Resources