fetch core data and save it to nsarray - ios

i think this is not tought but i'm facing problem with these.
i am fecthing core date and after fetching it i'm trying to save it into nsarray.
but every time last data from database is saving into array. i want every data inserted into databases.
suppose i have an attribute name account_name
i added A,B,C,X,Y,Z. in this code i'm just getting last value Z in my array. :(
but when i print it then i'm getting all data..
any solution ?
NSArray *fetchedObjects;
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [delegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Chart_of_Accounting" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *obj in fetchedObjects) {
debitArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
creditArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);
}

Try this
NSArray *fetchedObjects;
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [delegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Chart_of_Accounting" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
NSMutableArray *debitArray = [[NSMutableArray alloc] init];
NSMutableArray *creditArray = [[NSMutableArray alloc] init];
for (NSManagedObject *obj in fetchedObjects) {
[debitArray addObject:[obj valueForKey:#"account_name"]];
[creditArray addObject:[obj valueForKey:#"account_name"]];
NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);
}

Because, every time its get initialised . Use addObject
debitArray = creditArray = [[NSMutableArray alloc] init];
for (NSManagedObject *obj in fetchedObjects) {
[debitArray addObject:[obj valueForKey:#"account_name"]];
[creditArray addObject:[obj valueForKey:#"account_name"]];
}NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);

In your loop:
for (NSManagedObject *obj in fetchedObjects) {
debitArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
creditArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);
}
you are instantiating a new array each time (and overriding the previous one). That explains what is happening.
You should instantiate the array outside of the loop, then add your objects to it within the loop.
debitArray = [NSMutableArray arrayWithCapacity:[fetchedObjects count]];
creditArray = [NSMutableArray arrayWithCapacity:[fetchedObjects count]];
for (NSManagedObject *obj in fetchedObjects) {
[debitArray addObject:[obj valueForKey:#"account_name"]];
[creditArray addObject:[obj valueForKey:#"account_name"]];
NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);
}

Don't create duplicate values in different array.
return your fetchedObjects data as NSArray Type then retrive from coredata.
fetchedObjects=[self yourRetriveMethod];
for (NSManagedObject *obj in fetchedObjects) {
debitArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
creditArray = [NSMutableArray arrayWithObject:[obj valueForKey:#"account_name"]];
NSLog(#"Account Name: %#", [obj valueForKey:#"account_name"]);
}

Related

Getting Null Value From Database NSManagedObject

I am developing iOS app, which fetch data from Web Services and save it to local database and uses it various views as needed. The data is fetch from Web Service and save to database correctly. But while accessing data from NSManagedObject it show FAULT and the consequent NSDictionary shows null Values
The code follows:-
-(void)SaveData:(NSInteger)menuId categoryID:(NSInteger)catID caption:(NSString *)title parentID:(NSInteger)parentID
{
BBAppDelegate *appDelegate = [[BBAppDelegate alloc]init];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *userobj = [NSEntityDescription insertNewObjectForEntityForName:tableName
inManagedObjectContext:context];
[userobj setValue:[NSNumber numberWithInt:menuId] forKey:#"id"];
[userobj setValue:[NSNumber numberWithInt:catID] forKey:#"catid"];
[userobj setValue:[NSNumber numberWithInt:parentID] forKey:#"parentid"];
[userobj setValue:title forKey:#"caption"];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
NSLog(#"app dir: %#",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
}
-(NSArray *)fetchedData{
BBAppDelegate *appdelegate = [[BBAppDelegate alloc]init];
NSManagedObjectContext *context = [appdelegate managedObjectContext];
NSFetchRequest *readData = [[NSFetchRequest alloc] init];
[readData setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription
entityForName:tableName inManagedObjectContext:context];
[readData setEntity:entity];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:readData error:&error];
// for (Test *test in array)
// {
// NSLog(#"Test: %# ", test.text);
// }
NSLog(#"%#",results);
return results;
}
-(void)removeData{
BBAppDelegate *appdelegate = [[BBAppDelegate alloc]init];
NSManagedObjectContext *context = [appdelegate managedObjectContext];
NSFetchRequest *delData = [[NSFetchRequest alloc]init];
[delData setEntity:[NSEntityDescription entityForName:tableName inManagedObjectContext:context]];
[delData setIncludesPropertyValues:NO];
NSError *error = nil;
NSArray *result = [context executeFetchRequest:delData error:&error];
for (NSManagedObject *value in result) {
[context deleteObject:value];
}
NSError *saveError = nil;
[context save:&saveError];
}
-(void)table:(NSString *)nameTable{
tableName =nameTable;
}
- (instancetype)initWithTableName:(NSString *)tablename
{
[self table:tablename];
return self;
}
-(NSMutableArray *)buldMenu{
NSArray *array = [self fetchedData];
return [self getmenus:0 arr:array];
}
-(NSMutableArray *)getmenus:(NSInteger)parentID arr: (NSArray *)array
{
NSMutableArray *aray = [[NSMutableArray alloc]init];
for (NSManagedObject *dic in array) {
if (dic.faultingState != 0) {
NSLog(#"%lu",(unsigned long)dic.faultingState);
//return nil;
}
NSArray *keys = [[[dic entity] attributesByName] allKeys];
NSLog(#"%#",keys);
NSDictionary *dict = [dic dictionaryWithValuesForKeys:keys];
NSLog(#"%#",dic);
NSLog(#"%#",dict);
NSInteger pID = [[dict objectForKey:#"parentid"]integerValue];
if (pID == parentID) {
BBMenuEntry *entryMenu = [[BBMenuEntry alloc]init];
entryMenu.menuID = [[dict objectForKey:#"id"]integerValue];
entryMenu.catID = [[dict objectForKey:#"catid"]integerValue];
entryMenu.caption = [dict objectForKey:#"caption"];
entryMenu.subMenus = [self getmenus:entryMenu.menuID arr:array];
[aray addObject:entryMenu];
}
}
return aray;
}

objective-c pointer to 'int *' error when assigning data across relationships

In this tutorial http://www.raywenderlich.com/934/core-data-tutorial-for-ios-getting-started, the author creates two classes FailedBankInfo and FailedBankDetails from two core data entities, which have a relationship between them, and when he assigns the object failedBankDetails to the name of the relationship details on the failedBankInfo object/pointer like this
failedBankInfo.details = failedBankDetails;
it generates this error
implicit conversion of an objective-c pointer to 'int *' is disallowed with arc
and the same error is generated when he assigns info.details to the pointer FailedBankDetails * details
for (FailedBankInfo *info in fetchedObjects) {
NSLog(#"Name: %#", info.name);
FailedBankDetails *details = info.details;
NSLog(#"Zip: %#", details.zip);
}
Can you explain why this is happening?
This is the full code that he instructs reader to insert into applicationDidFinishLaunching
NSManagedObjectContext *context = [self managedObjectContext];
FailedBankInfo *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
failedBankInfo.name = #"Test Bank";
failedBankInfo.city = #"Testville";
failedBankInfo.state = #"Testland";
FailedBankDetails *failedBankDetails = [NSEntityDescription insertNewObjectForEntityForName:#"FailedBankDetails"
inManagedObjectContext:context];
failedBankDetails.closeDate = [NSDate date];
failedBankDetails.updateDate = [NSDate date];
failedBankDetails.zip = [NSNumber numberWithInt:12345];
failedBankDetails.info = failedBankInfo;
failedBankInfo.details = failedBankDetails;
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
// Test listing all FailedBankInfos from the store
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (FailedBankInfo *info in fetchedObjects) {
NSLog(#"Name: %#", info.name);
FailedBankDetails *details = info.details;
NSLog(#"Zip: %#", details.zip);
}
Before generating classes for the entities, he performed the same task/test just using the managedObject and there was no problem
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[failedBankInfo setValue:#"Test Bank" forKey:#"name"];
[failedBankInfo setValue:#"Testville" forKey:#"city"];
[failedBankInfo setValue:#"Testland" forKey:#"state"];
NSManagedObject *failedBankDetails = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankDetails"
inManagedObjectContext:context];
[failedBankDetails setValue:[NSDate date] forKey:#"closeDate"];
[failedBankDetails setValue:[NSDate date] forKey:#"updateDate"];
[failedBankDetails setValue:[NSNumber numberWithInt:12345] forKey:#"zip"];
[failedBankDetails setValue:failedBankInfo forKey:#"info"];
[failedBankInfo setValue:failedBankDetails forKey:#"details"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"FailedBankInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"Name: %#", [info valueForKey:#"name"]);
NSManagedObject *details = [info valueForKey:#"details"];
NSLog(#"Zip: %#", [details valueForKey:#"zip"]);
}
That looks as if the "details" property of "FailedBackInfo" is declared as
#property (nonatomic) int *details;
and not – as it should be – as
#property (nonatomic, retain) FailedBankDetails *details;
In the tutorial it says you can change the type of the info/detail variable in the h file depending on which one you create first manually. I found that this didn't work. I think your problem may be solved by deleting the subclass that you created first and then recreating it. That way it should link up with the entity relationships to info/detail (whichever you did second) properly

executeFetchRequest taking too long .

Even though I don't have more than 3 records in my table , and a single table. Method : executeFetchRequest takes too long
loanIDArray=[[NSMutableArray alloc]init];
appDelegate=[[UIApplication sharedApplication] delegate];
context=[appDelegate managedObjectContext];
entityDesc=[NSEntityDescription entityForName:#"Personal_Info" inManagedObjectContext:context];
NSFetchRequest* request=[[NSFetchRequest alloc]init];
[request setEntity:entityDesc];
NSPredicate* predicate=[NSPredicate predicateWithFormat:#"status_of_form==%#",#"Completed"];
[request setPredicate:predicate];
NSError* fetchError;
NSError* error;
This line takes too long
NSArray* objects = [context executeFetchRequest:request error:&fetchError];
if (!fetchError) {
for (NSManagedObject* obj in objects) {
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}
else
NSLog(#"Status Fetch Error : %#",fetchError.description);
[context save:&error];
if (!error)
NSLog(#"count : %d",loanIDArray.count );
else
NSLog(#"error : %#",error.description);
try replace this code:
if (!fetchError) {
for (NSManagedObject* obj in objects) {
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}
with this to avoid iteration:
if (!fetchError) {
loanIDArray = [objects valueForKeyPath:#"app_id"];
}
Try this.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:entityDesc];
NSError *error = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"status_of_form==%#",#"Completed"];
[fetchRequest setPredicate:predicate];
NSArray *request = [context executeFetchRequest:fetchRequest error:&error];
if (!request.count==0) {
for (int i = 0; i<=request.count-1;i++) {
NSManagedObject *obj = [request objectAtIndex:i];
[loanIDArray addObject:[obj valueForKey:#"app_id"]];
}
}

XMPP, CoreData - how to load only self and destination user messages?

I save to core data and load all messages with code below, but how can I load only messages for 2 users, for self user and for destination user, I want base it on user JID.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [[self appDelegate].xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
fetchRequest.entity = messageEntity;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:YES];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
//Now you get the NSArray with element type of "XMPPMessageArchiving_Message_CoreDataObject"
assuming your message objects have a from relationshit to a User entity.
As simple as adding (before executing the request):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"from = %# OR from = %#",selfUser,otherUser];
Where selfUser and otherUser are User core data managed objects or managed object IDs of users.
if you use a field identifier (highly not recomended):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJID.bare = %# OR bareJID.bare = %#",selfUser.jid,otherUser.jid];
You might want to read THIS
I have used following method and it worked correctly :)
-(void)checkForPastMessageAndDisplayIt
{
NSString *strmyid = #"user1#domain";
NSString *strBuddy = #"user2#domain";
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_message_achiving];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *messagesArray = [moc executeFetchRequest:fetchRequest error:&error];
[messagesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id messageObject = [messagesArray objectAtIndex:idx];
if ([messageObject isKindOfClass:[XMPPMessageArchiving_Message_CoreDataObject class]]) {
XMPPMessageArchiving_Message_CoreDataObject *currentMessageCoreDataObject = (XMPPMessageArchiving_Message_CoreDataObject*)messageObject;
XMPPMessage *message = currentMessageCoreDataObject.message;
if (message!=nil) {
[messages addObject:message];
}
}
}];
}
You can use like that
-(void)testMessageArchiving {
NSString *strmyid = #"myid";
NSString *strBuddy ="toid";
NSLog(#"my id and buddy is is %# and %#",strmyid,strBuddy);
XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
NSError *error;
NSArray *messages = [moc executeFetchRequest:request error:&error];
// NSLog(#"the history of messages is %#",messages);
[self print:[[NSMutableArray alloc]initWithArray:messages]];

iOS NSManagedObject Data <fault> while deleting

I am having some difficulties in deleting an entry from Core Data.
It works but the NSManagedObject data has no values (fault), and so sometimes the wrong entry will be deleted.
In my deleteWholeDatabase method the objects are filled with values.
And in the deleteEntryFromDatabase method are no values. But why?
Here are my methods:
-(NSArray*)databaseRequest{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:currentEntity inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSError *error;
NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
return items;
}
-(void)deleteWholeDatabase{
for (NSManagedObject *objectToDelete in [self databaseRequest]) {
[managedObjectContext deleteObject:objectToDelete];
NSLog(#"%# object deleted",objectToDelete);
}
[self saveContext];
NSLog(#"All entries deleted!");
}
-(void)deleteEntryFromDatabase:(NSManagedObjectContext*)context forEntry:(NSIndexPath*)indexPath{
NSManagedObject *objectToDelete=[[self databaseRequest] objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:[managedObjectContext objectWithID:[objectToDelete objectID]]];
[self saveContext];
NSLog(#"%# deleted!",[managedObjectContext objectWithID:[objectToDelete objectID]]);
}
The wrong entry is being deleted because each request return the itens in a different order. Try deleting the intens by comparing their memory adress
Instead of keeping a calling [self databaseRequest] everywhere, I would keep a local copy of NSManagedObjectID's as an array.
- (void)init {
self.entities = [self databaseRequest];
}
-(NSArray*)databaseRequest{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:currentEntity inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSError *error;
NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSMutableArray *itemIDs = [[NSMutableArray alloc] initWithCapacity:[items count]];
for (NSManangedObject *item in items) {
[itemIDs addObject:[item objectID]];
}
return items;
}
Then everywhere where you call [self databaseRequest], you will get an have the correct NSManagedObjectID. Then you just need to get the correct entity from the ID.

Resources