-3

I'm trying to fetch all of the data from a particular Core Data Entity and place each record into a string. However the following code only prints the LAST record that it accesses. What am I doing wrong?

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Order" inManagedObjectContext:managedObjectContext];

[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];


NSLog(@"=============================================");
NSLog(@"Generating Data To Be Sent");
for (NSManagedObjectContext * info in fetchedObjects) 

{

    NSLog(@"Client Name: %@", [info valueForKey:@"clientName"]);
    NSLog(@"Client Account Number: %@", [info valueForKey:@"clientAccountNumber"]); 
    NSLog(@"Product Code: %@", [info valueForKey:@"productCode"]);
    NSLog(@"Product Price: %@", [info valueForKey:@"productPrice"]);
    NSLog(@"Product Quantity: %@", [info valueForKey:@"productQuantity"]);
    NSLog(@"Order Total: %@", [info valueForKey:@"orderTotal"]);
    NSLog(@"Order ID : %@", [info valueForKey:@"orderID"]); 
    NSLog(@"Transaction ID: %@", [info valueForKey:@"transactionID"]);
    NSLog(@"Sales Rep ID : %@", [info valueForKey:@"salesRepresentativeID"]);

}

NSString * printedData;
NSString * formattedData;

NSString * clientName;
NSString * clientAccount;
NSString * productCode;
NSString * productQuantity;
NSString * productPrice;
NSString * orderTotal;
NSString * orderID;
NSString * transactionID;
NSString * salesRepID;



for(NSManagedObject * info in fetchedObjects)

{

    clientName = [info valueForKey:@"clientName"];
    clientAccount =  [info valueForKey:@"clientAccountNumber"]; 
    productCode =  [info valueForKey:@"productCode"];
    productPrice =  [info valueForKey:@"productPrice"];
    productQuantity = [info valueForKey:@"productQuantity"];
    orderTotal =  [info valueForKey:@"orderTotal"];
    orderID = [info valueForKey:@"orderID"]; 
    transactionID = [info valueForKey:@"transactionID"];
    salesRepID = [info valueForKey:@"salesRepresentativeID"];


    formattedData = [NSString stringWithFormat:@"|%@|%@|%@|%@|%@|%@|%@|%@|%@|\n",clientName,clientAccount,productCode,productQuantity,productPrice,orderID,transactionID,orderTotal,salesRepID];

    printedData = formattedData;

}

NSLog(@"=============================================");
NSLog(@"Data Generated");
NSLog(@"%@",printedData);
[fetchRequest release];

NSMutableArray *recipients = [[NSMutableArray alloc] initWithCapacity:1];
[recipients addObject:toEmail.text];

MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:toSubject.text];
[controller setMessageBody:printedData isHTML:NO];
[controller setToRecipients:recipients];

[self presentModalViewController:controller animated:YES];
[controller release];
Gray
  • 115,027
  • 24
  • 293
  • 354
  • the line `NSLog(@"%@",printedData);` should be inside the for-loop – Felix Mar 21 '12 at 13:51
  • ok but thats just an NSLog , if you can see the printedData Variable is in [controller setMessageBody:printedData isHTML:NO]; , thats whats giving me problems , only 1 record is being printed – Chris Calleja Urry Mar 21 '12 at 14:08
  • Word-for-word duplicate of [this question](http://stackoverflow.com/questions/9806668/printing-the-contents-of-a-fetchrequest) by same asker. – FluffulousChimp Mar 21 '12 at 15:02

2 Answers2

1

To fix your initial problem you need to use an NSMutableString. There is no need for formattedData variable.

...
NSMutableString * printedData = [NSMutableString string];
...

for(NSManagedObject * info in fetchedObjects)
{
    ...
    [printedData appendFormat:@"|%@|%@|%@|%@|%@|%@|%@|%@|%@|\n",clientName,clientAccount,productCode,productQuantity,productPrice,orderID,transactionID,orderTotal,salesRepID];
}
...

Your next issue is how inefficient this code is. You are looping over the same collection twice, once to log, once to create a formatted string. You can combine this into one loop. Also all of the variables are defined outside of the scope of the for loop that they are used in, you could simply just declare each one on a line like this.

for(NSManagedObject * info in fetchedObjects)
{
    NSString *clientName = [info valueForKey:@"clientName"];
    NSString *clientAccount =  [info valueForKey:@"clientAccountNumber"];
    ...
    //Log them all
    NSLog(@"%@",clientName);
    NSLog(@"%@",clientAccount);
    ...
}
Joe
  • 56,979
  • 9
  • 128
  • 135
  • just managed to fix it actually , i created an array and stored all of the values , it works , but i have some unwanted text , to be exact , its this: phase: Ended tap count: 1 window: > view: > location in window: {428, 471} previous location in window: {425, 469} location in view: {149, 165} previous location in view: {146, 163}, – Chris Calleja Urry Mar 21 '12 at 14:38
  • Time to start debugging, that means you are printing the wrong kind of object somewhere. – Joe Mar 21 '12 at 14:43
0

If you are trying to concatenate all of the formattedData strings into a single NSString printedData, that's not what your code is doing, right? In each iteration over your managed objects, you are re-assigning printedData. That's why you only get the last record.

I'm inferring that you want printed data to accumulate all of the formattedData strings derived from your NSManagedObject instances. If that's the case, then you need to declare printedData as an NSMutableString and append formattedData strings to that mutable string in each iteration over your managed objects, e.g.

for( NSManagedObject *info in fetchedObjects )
{
    formattedData = [NSString stringWithFormat://blah blah blah
    [printedData appendString:formattedData];
}
FluffulousChimp
  • 9,157
  • 3
  • 35
  • 42
  • It was working until it hits [array addObject: printedData] with error EXC_BAD_ACCESS ... Any ideas ? i put this code just after printed data = formatted data; – Chris Calleja Urry Mar 21 '12 at 15:28