I am developing a chat app which needs contacts for chatting but when first time it is not showing the contacts again restart the app fetch then it is showing here is my code
-(NSMutableArray *)getAllContacts {
sleep(6);
// The user has previously given access, add the contact
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBookRef);
CFArrayRef allPeople = (ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBookRef, source, kABPersonSortByFirstName));
CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef);
NSMutableArray* items = [[NSMutableArray alloc] init];
if (!allPeople || !nPeople) {
NSLog(#"people nil");
}
CFStringRef description = CFCopyDescription(allPeople);
NSLog(#"Array %#", description);
CFRelease(description);
for (int i = 0; i < nPeople; i++) {
// #autoreleasepool {
//data model
ContactsData *contacts = [ContactsData new];
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//get First Name
CFStringRef firstName = (CFStringRef)ABRecordCopyValue(person,kABPersonFirstNameProperty);
contacts.firstNames = (__bridge NSString*)firstName;
if (firstName != NULL) {
CFRelease(firstName);
}
//get Last Name
CFStringRef lastName = (CFStringRef)ABRecordCopyValue(person,kABPersonLastNameProperty);
contacts.lastNames = (__bridge NSString*)lastName;
if (lastName != NULL) {
CFRelease(lastName);
}
if (!contacts.firstNames) {
contacts.firstNames = #"";
}
if (!contacts.lastNames) {
contacts.lastNames = #"";
}
contacts.contactId = ABRecordGetRecordID(person);
//append first name and last name
contacts.fullname = [NSString stringWithFormat:#"%# %#", contacts.firstNames, contacts.lastNames];
// get contacts picture, if pic doesn't exists, show standart one
CFDataRef imgData = ABPersonCopyImageData(person);
NSData *imageData = (__bridge NSData *)imgData;
contacts.image = [UIImage imageWithData:imageData];
if (imgData != NULL) {
CFRelease(imgData);
}
if (!contacts.image) {
contacts.image = [UIImage imageNamed:#"avatar.png"];
}
//get Phone Numbers
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i=0; i<ABMultiValueGetCount(multiPhones); i++) {
#autoreleasepool {
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i);
NSString *phoneNumber = CFBridgingRelease(phoneNumberRef);
phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:#""];
if (phoneNumber != nil)[phoneNumbers addObject:phoneNumber];
//NSLog(#"All numbers %#", phoneNumbers);
}
}
if (multiPhones != NULL) {
CFRelease(multiPhones);
}
[contacts setNumbers:phoneNumbers];
//get Contact email
NSMutableArray *contactEmails = [NSMutableArray new];
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex i=0; i<ABMultiValueGetCount(multiEmails); i++) {
#autoreleasepool {
CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, i);
NSString *contactEmail = CFBridgingRelease(contactEmailRef);
if (contactEmail != nil)[contactEmails addObject:contactEmail];
// NSLog(#"All emails are:%#", contactEmails);
}
}
if (multiPhones != NULL) {
CFRelease(multiEmails);
}
[contacts setEmails:contactEmails];
[items addObject:contacts];
#ifdef DEBUG
NSLog(#"Person is: %#", contacts.firstNames);
NSLog(#"Phones are: %#", contacts.numbers);
NSLog(#"Email is:%#", contacts.emails);
#endif
}
// } //autoreleasepool
CFRelease(allPeople);
CFRelease(addressBookRef);
CFRelease(source);
return items;
}
now i am getting the contacts and now i am fetching the contacts from
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController == nil)
{
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_roster];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPUserCoreDataStorageObject"
inManagedObjectContext:moc];
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"sectionNum" ascending:YES];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
NSArray *sortDescriptors = #[sd1, sd2];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:moc
sectionNameKeyPath:#"sectionNum"
cacheName:nil];
[fetchedResultsController setDelegate:self];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
{
DDLogError(#"Error performing fetch: %#", error);
NSLog(#"Error performing fetch");
}
}
return fetchedResultsController;
}
now assigning this fetched controller to array like
self.UserArray=[[[self fetchedResultsController] fetchedObjects] mutableCopy];
but unable to fetch the contacts to tableview where i miss please help me out
Related
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'Unacceptable type of value for
attribute: property = "XXXXX"; desired type = NSNumber; given type =
NSTaggedPointerString; value = 0.'
Tried: [enter image description here][1]
[message setValue:localID forKey:#"local_id"];
localID is of type NSNumber
DataModel image: [1]: https://i.stack.imgur.com/7WTlU.png
[self insertInLocatDB:print_data entityName:#"Message_data" withPredicate:#"receiver_id" filterWith:#"unique_id"];
Using this to insert into CoreData:
-(void)insertInLocatDB :(NSMutableArray *)arr_msg entityName:(NSString*)name withPredicate:(NSString*)predicateText filterWith:(NSString*)filterText
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:name inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id =[self getMaxLocalId:name];
for(int i=0; i<[arr_msg count]; i++)
{
[fetched_data removeAllObjects];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"%# like %# ",predicateText,[[arr_msg objectAtIndex:i]objectForKey:predicateText]];
[request setPredicate:predicate];
NSError *error;
NSArray *matchingData=[app.context executeFetchRequest:request error:&error];
local_id=local_id+1;
for (NSManagedObject *obj in matchingData)
{
[fetched_data addObject:[obj valueForKey:filterText]];
}
NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
if(![fetched_data containsObject:filter])
{
NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
[arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
[arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
for (int i=0;i<[arr_keys count];i++)
{
if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
&& ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
{
[message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
}
}
[arr_keys removeAllObjects];
[arr_values removeAllObjects];
}
}
}
If you have a core data attribute as shown in my screen shot.
Then, the following snippet of code will work for you.
BOOL result;
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
NSManagedObject *newMessage = [NSEntityDescription insertNewObjectForEntityForName:#"message"
inManagedObjectContext:context];
[newMessage setValue:[NSNumber numberWithInt:local_id] forKey:#"local_id"];
[newMovie setValue:movieName forKey:#"message"];
NSError *error = nil;
// Save the object to persistent store
result = YES;
if (![context save:&error]) {
result = NO;
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
return result;
and a function to get the managed object context
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
Edited Code of Sandhya.
-(NSInteger)getMaxLocalId :(NSString*)entitiyName
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:entitiyName inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id = 0;
request.fetchLimit = 1;
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"local_id" ascending:NO]];
NSError *error = nil;
local_id=[[app.context executeFetchRequest:request error:&error].firstObject integerValue];
return local_id;
}
Then used the following to insert in to CoreData
NSInteger local_id =[self getMaxLocalId:name];
local_id=local_id+1;
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
make sure you get the local_id.
As you have NSInteger, For conversion you should use [NSNumber numberWithInteger:] Instead of [NSNumber numberWithInt:]
UPDATE 2 :
NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
if(![fetched_data containsObject:filter])
{
NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
[arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
[arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
[message setValue:[NSNumber numberWithInteger:local_id] forKey:#"local_id"];
for (int i=0;i<[arr_keys count];i++)
{
if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
&& ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
{
if(![[arr_keys objectAtIndex:i] isEqualToString:#"local_id"]){
[message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
}
}
}
[arr_keys removeAllObjects];
[arr_values removeAllObjects];
}
-(NSInteger)getMaxLocalId :(NSString*)entitiyName
{
NSEntityDescription *entitydesc=[NSEntityDescription entityForName:entitiyName inManagedObjectContext:app.context];
NSFetchRequest *request=[[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSInteger local_id = 0;
request.fetchLimit = 1;
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"local_id" ascending:NO]];
NSError *error = nil;
local_id=[[app.context executeFetchRequest:request error:&error].firstObject integerValue];
return local_id;
}
Then used the following to insert in to CoreData
NSInteger local_id =[self getMaxLocalId:name];
local_id=local_id+1;
[message setValue:myNumber forKey:#"local_id"];
I'm trying to update certain currency abbreviations in the coredata with this function.
- (void)updateCurrencies
{
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:managedObjectContext]];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"Number of data : %lu", (unsigned long)[results count]);
for (int i = 0; i < [results count]; i++) {
Transaction* t = [results objectAtIndex:0];
NSLog(#"currency: %#", t.currency);
if ([t.currency isEqualToString:#"CAN"]) {
t.currency = #"CAD";
NSLog(#"new currency set.");
}
[self saveContext];
}
}
}
I call this function in didFinishLaunchingWithOptions. Now, the log does inform me that t.currency has been updated to CAD. However when I retrieve the data again in HomeViewController and log the currency, it is back to CAN. This is the code in HomeViewController,
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *transaction = [NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:_managedObjectContext];
[request setEntity:transaction];
request.predicate = [NSPredicate predicateWithFormat:#"transactionToUser = %#", [self.content objectAtIndex:i]];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"postdate" ascending:NO];
NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];
[request setSortDescriptors:descriptors];
NSError *error = nil;
NSMutableArray *mutableResult = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableResult == nil) {
//handle error
}
for (int k = 0; k < [mutableResult count]; k++) {
Transaction *t = [mutableResult objectAtIndex:k];
NSLog(#"currency xx: %#", t.currency);
}
What am I doing wrong? Any help is appreciated. Thanks.
Fixed it with a different for loop.
for (Transaction *t in results)
{
...
}
I am parsing data from JSON and Storing to CoreData in the same time i am displaying the the data to tableview but the problem i am having is data is displaying only after download completed but i dont want like this i want to download the data in background and display the data while downloading is processed also how can i do this
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
arrayData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSError *error;
NSManagedObjectContext *context = [appDelegate managedObjectContext];
context = [appDelegate managedObjectContext];
for (int i = 0; i < [arrayData count]; i++) {
idNum = [arrayData objectAtIndex:i][#"id"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Discount"];
[request setPredicate:[NSPredicate predicateWithFormat:#"cID = %#",idNum]];
[request setFetchLimit:1];
NSUInteger count = [context countForFetchRequest:request error:&error];
if (count == NSNotFound) {
NSLog(#"ERROR");
}else if (count == 0) {
NSLog(#"New Data Coming");
name = [arrayData objectAtIndex:i][#"name"];
summary = [arrayData objectAtIndex:i][#"summary"];
region = [arrayData objectAtIndex:i][#"region"];
imageURL = [arrayData objectAtIndex:i][#"images"][#"logo"];
id benefits1 = [arrayData objectAtIndex:i][#"benefits"];
benefiteString = [NSString stringWithFormat:#"%# %#",[benefits1 objectAtIndex:0][#"key"],[benefits1 objectAtIndex:0][#"value"]];
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
dateUpdate = [arrayData objectAtIndex:i][#"updated_at"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat: #"yyyy-MM-dd'T'HH:mm:ss.sssZ"];
NSDate *date =[dateFormatter dateFromString:dateUpdate];
[dateFormatter setDateFormat:#"yyyy/MM/dd HH:mm:ss"];
NSLog(#"DAte : %#",date);
Discount * d = [NSEntityDescription insertNewObjectForEntityForName:#"Discount" inManagedObjectContext:context];
d.name = name;
d.summary = summary;
d.regions = region;
d.cID = idNum;
d.imageLogo = data;
d.updated_at = date;
d.benefits = benefiteString;
if (![context save:&error]) {
NSLog(#"Getting error while saving data");
}
else{
NSLog(#"Saved");
}
}
}
[sharedAppDelegate dismissGlobalHUD];
[listTableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_myArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCellClass = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (customCellClass == nil)
{
customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
customCellClass.nameLabel.text = [[_myArray objectAtIndex:indexPath.row]name];
customCellClass.cityLabel.text =[[_myArray objectAtIndex:indexPath.row]regions];
customCellClass.detailLabel.text = [[_myArray objectAtIndex:indexPath.row]summary];
NSData * d = [[_myArray objectAtIndex:indexPath.row]imageLogo];
customCellClass.mainImage.image = [UIImage imageWithData:d];
customCellClass.benefitsLabel.text = [[_myArray objectAtIndex:indexPath.row]benefits];
[sharedAppDelegate dismissGlobalHUD];
return customCellClass;
}
-(void)dataDidSave
{
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Discount" inManagedObjectContext:context]; [fetchRequest setEntity:entity];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
self.myArray = result;
[listTableView reloadData];
}
-(void)viewWillAppear:(BOOL)animated
{
[sharedAppDelegate showGlobalProgressHUDWithTitle:#"Loading..."];
[self dataDidSave];
}
In connectionDidFinishLoading: try something like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {
// Process your data and then incrementally call
dispatch_async(dispatch_get_main_queue(),^ {
[listTableView reloadData];
});
}
});
I have Three tables, One to many relationship between Session and Album , One to many relationship between Album to songs , When I tried to fetch data from songs Then I get nothing
Here is my readFRomDB func
-(void)readDataFromDB{
AppDelegate *delegates = (AppDelegate *) [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegates managedObjectContext];
if (runningSessionArray.count > 0) {
[runningSessionArray removeAllObjects];
}
NSManagedObjectContext *moc = [self managedObjectContext];
NSArray *searchResults = nil;
NSArray *searchAlbumsResults = nil;
NSArray *searchSongsResult=nil;
NSFetchRequest * fetchRequest1 = [[NSFetchRequest alloc] init];
NSFetchRequest * fetchRequest2 = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"RunningSession" inManagedObjectContext:moc];
NSFetchRequest *requestData = [[NSFetchRequest alloc] init];
[requestData setEntity:entityDescription];
[requestData setFetchLimit:1] ;
NSError *error;
// if get a entity, that means exists, so fetch it.
searchResults = [managedObjectContext executeFetchRequest:requestData error:&error];
for ( RunningSession *session in searchResults) {
// Update the Records
self.runnningSessionId=[NSString stringWithFormat:#"%#",session.runningSessionID];
self.title=session.title;
self.desc=[NSString stringWithFormat:#"%#",session.desc];
[fetchRequest1 setEntity:[NSEntityDescription entityForName:#"Albums"
inManagedObjectContext:session.managedObjectContext]];
[fetchRequest1 setEntity:entityDescription];
[fetchRequest1 setFetchLimit:1] ;
searchAlbumsResults = [session.managedObjectContext executeFetchRequest:fetchRequest1 error:&error];
NSMutableArray *tagNamesArray = [[NSMutableArray alloc] init];
//NSLog(#"Local Discount Shops:%#",discounts.shops);
NSSet *tagA = session.albums;
if (tagA.count>0) {
for (Albums *tag in tagA
) {
// NSLog(#"tag:%#",tag);
NSString *albumID;
NSString *aTitle;
NSString *aPrice;
NSString *aDuration;
NSString *aUrl;
NSString *aPurchasedHtml;
NSString *aNonPurchasedHtml;
if (tag.albumID != NULL) {
albumID = [NSString stringWithFormat:#"%#",tag.albumID]; //tag.shopId;
}else{
albumID = #"";
}
if (tag.title != NULL) {
aTitle = tag.title;
}
else{
aTitle = #"";
}
if (tag.price != NULL) {
aPrice = tag.price;
}
else{
aPrice = #"";
}
if (tag.duration != NULL) {
aDuration = tag.duration;
}
else{
aDuration = #"";
}
if (tag.url != NULL) {
aUrl = tag.url;
}
else{
aUrl = #"";
}
if (tag.purchasedHtml != NULL) {
aPurchasedHtml = tag.purchasedHtml;
}
else{
aPurchasedHtml = #"";
}
if (tag.nonPurchasedHtml != NULL) {
aNonPurchasedHtml = tag.nonPurchasedHtml;
}
else{
aNonPurchasedHtml = #"";
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:albumID,#"Id",aTitle,#"Title",aPrice,#"Price", aDuration,#"Duration",
albumUrl,#"Url",aPurchasedHtml,#"PurchasedItemsHtml",aNonPurchasedHtml,#"NonPurchasedItemsHtml", nil];
[tagNamesArray addObject:dict];
NSLog(#"tag.shop:%#",tag.songs);
[fetchRequest2 setEntity:[NSEntityDescription entityForName:#"Songs"
inManagedObjectContext:tag.managedObjectContext]];
[fetchRequest2 setEntity:entityDescription];
[fetchRequest2 setFetchLimit:1];
searchSongsResult = [tag.managedObjectContext executeFetchRequest:fetchRequest2 error:&error];
NSMutableArray *songsNamesArray = [[NSMutableArray alloc] init];
//NSLog(#"Local Discount Shops:%#",discounts.shops);
NSSet *tags = tag.songs;
if (tags.count>0) {
for (Songs *tag in tags) {
// NSLog(#"tag:%#",tag);
NSString *sID;
NSString *sTitle;
NSString *startTime;
if (tag.songsId !=NULL) {
sID = [NSString stringWithFormat:#"%#",tag.songsId]; //tag.shopId;
}else{
sID = #"";
}
if (tag.title != NULL) {
sTitle = tag.title;
}
else{
sTitle = #"";
}
if (tag.startTime != NULL) {
startTime = tag.startTime;
}
else{
startTime = #"";
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:sID,#"Id",sTitle,#"Title",startTime,#"Duration", nil];
[songsNamesArray addObject:dict];
}
}
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:albumID,#"Id",albumTitle,#"Title",albumPrice,#"Price",albumDuration,#"Duration",albumUrl,#"Url",albumPurchasedHtml,#"PurchasedItemsHtml",albumNonPurchasedHtml,#"NonPurchasedItemsHtml",songsNamesArray,#"Songs", nil];
}
}
// NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:#"firstName = 'Bob'"];
// NSLog(#"Bobs: %#", [discounts filteredArrayUsingPredicate:bobPredicate]);
NSMutableArray *albumArray = [[NSMutableArray alloc] init];
albumArray = [tagNamesArray mutableCopy];
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:self.runnningSessionId,#"Id",title,#"Title",self.title,#"title",self.desc,#"Description",albumArray,#"Albums", nil];
[self.runningSessionArray addObject:dict];
// [self StudentDiscountData];
// NSLog(#"studentDataArray:%#",self.studentDataArray);
}
NSLog(#"RunningSession: %#",self.runningSessionArray);
}
I think you don't need to all those steps getting session data is enough and from that you can get Albums list as you set the one to many relationship. And from each Album you will get Songs
AppDelegate *delegates = (AppDelegate *) [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegates managedObjectContext];
if (runningSessionArray.count > 0) {
[runningSessionArray removeAllObjects];
}
NSManagedObjectContext *moc = [self managedObjectContext];
NSArray *searchResults = nil;
NSArray *searchAlbumsResults = nil;// not required
NSArray *searchSongsResult=nil;//not required
NSFetchRequest * fetchRequest1 = [[NSFetchRequest alloc] init];//not required
NSFetchRequest * fetchRequest2 = [[NSFetchRequest alloc] init];//not required
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"RunningSession" inManagedObjectContext:moc];
NSFetchRequest *requestData = [[NSFetchRequest alloc] init];
[requestData setEntity:entityDescription];
[requestData setFetchLimit:1] ;
NSError *error;
// if get a entity, that means exists, so fetch it.
searchResults = [managedObjectContext executeFetchRequest:requestData error:&error];
//This returns array of sessions
for ( RunningSession *session in searchResults) {
NSArray *albumsArray = session.albums; //This returns Albums list as you set one to many relation
for ( Album *album in albumsArray) {
NSArray *songsArray = album.songs; //This returns songs list as you set one to many relation
}
}
I have two arrays, one is an array from a fetch request of core-data (array1), the other is from data that is being pulled from the web(array2). What I want to do is compare array1 to array2 and any items that are in array2 that are not in array1 need to be added to core-data.
The data I'm pulling from has id's associated with each person. When I create a new "person" entity I save this id with it as well. I'm not sure how to compare the arrays using the Person's id, or even how to access that within an array.
Here is the fetch request:
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSError *error = nil;
[fetch setEntity:[NSEntityDescription entityForName:#"Person" inManagedObjectContext:self.managedObjectContext]];
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:#"Pid" ascending:YES];
request.sortDescriptors = #[sorter];
NSArray *items = [self.managedObjectContext executeFetchRequest:request error:&error];
I have the fetch sorted in the same way array2 with the new data is sorted. I'm just not sure how to compare the two and then add the new items into core-data. Please help?
Update:
NSDictionary *qDict = [JSON objectForKey:#"person"];
NSArray *qArry = [JSON objectForKey:#"person"];
//Used to print the id's
_testArray = [NSMutableArray arrayWithArray:[qDict valueForKey:#"id"]];
for (NSNumber *numb in _testArray) {
NSLog(#"id = %#", numb);
}
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Person"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Pid IN %#", [qDict valueForKey:#"Pid"]];
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"Pid" ascending:YES]]];
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(#"%d how many items from the fetch", items.count);
for (NSDictionary *qdt in qArry) {
NSUInteger currentIndex = 0;
Person *q = nil;
if ([items count] > currentIndex) {
q = [items objectAtIndex:currentIndex];
}
if ([q.Pid integerValue] == [[qdt objectForKey:#"id"] integerValue]) {
// Either update the object or just move on
}
else {
// Add the object to core data
q = [NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:self.managedObjectContext];
q.url = [qdt valueForKey:#"url"];
q.Pid = [qdt objectForKey:#"id"];
q.text = [qdt valueForKey:#"personText"];
NSError *error = nil;
[_managedObjectContext save:&error];
}
currentIndex++;
}
//[_managedObjectContext save:&error];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error retrieving data" message:#"Please try again" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[av show];
}];
First you can fetch the list of objects stored in your core data based on person's IDs that you retrieve from the web (idArray) and sort them based on the ID:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Person"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"id IN %#", idArray];
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES]]];
This will return you the list of objects that the id can also be found in the objects you retrieve from the web. Let us call this storedRecords array. Then you can do the following:
Set a counter,
Iterate over the downloadedArray (this is the array containing the objects retrieved from the web and it must be sorted by id too),
Use objectAtIndex in the storedRecords array,
Check the id of the storedManagedObject if it matches the id of the record object
if it does not match, it is a new object that you can save into core data. Otherwise, it is an existing object.
Increase the counter.
Here is an example:
int currentIndex = 0;
for (NSDictionary *record in downloadedArray) {
NSManagedObject *storedManagedObject = nil;
if ([storedRecords count] > currentIndex) {
storedManagedObject = [storedRecords objectAtIndex:currentIndex];
}
if ([[storedManagedObject valueForKey:#"id"] integerValue] == [[record valueForKey:#"id"] integerValue]) {
//this will be existing object in core data
//you can update the object if you want
} else {
//this will be new object that you can store into core data
}
currentIndex++;
}
This is similar to what is mentioned here:
http://www.raywenderlich.com/15916/how-to-synchronize-core-data-with-a-web-service-part-1
maybe you can do something like this:
NSMutableArray *webData = [NSMutableArray arrayWithObjects:#"object 1",#"object 2",#"object 3",#"object 4", nil];
NSMutableArray *coreData = [NSMutableArray arrayWithObjects:#"object 2",#"object 4", nil];
NSMutableArray *newData = [NSMutableArray arrayWithArray:webData];
[newData removeObjectsInArray:coreData];
//output "object 1", "object 3"
or if you have a custom NSObject inside the array and compare it with its primary key maybe you can do something like:
NSMutableArray *webData = [NSMutableArray arrayWithObjects:test1,test2,test3,test4, nil];
NSMutableArray *coreData = [NSMutableArray arrayWithObjects:test2,test3, nil];
__block NSMutableArray *newData = [NSMutableArray new];
[webData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
__block testObject *object = (testObject *)obj;
__block BOOL isExisting = NO;
[coreData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
testObject *innerObject = (testObject *)obj;
if(object._id == innerObject._id)
isExisting = YES;
}];
if(!isExisting)
[newData addObject:object];
}];
//output will be object 1 and object 4
Try this
NSMutableArray *array1 = [[NSMutableArray alloc] initWithObjects:#"a",#"a",#"a",#"d",#"b",#"b",#"c",#"a",#"c",nil];
NSMutableArray *array2 = [[NSMutableArray alloc] initWithObjects:[NSString stringWithFormat:#"%#",[array1 objectAtIndex:0]], nil];;
for(int i = 0;i<[array1 count];i++)
{
if ([array2 containsObject:[array1 objectAtIndex:i]]) {
NSLog(#"do nothing");
}
else{
[array2 addObject:[array1 objectAtIndex:i]];
NSLog(#"array2 is %#",array2);
}
NSLog(#"finally array2 is %#",array2);
}
array2 will be as { a,d,b,c }