2

I am exporting the core data into csv via mail composer using CHCSVParser(by Dave DeLong) but the issue is that it is taking the core data table name instead of row values.

Also, i want them in a particular order.e.g.like "Sewer No", "Manhole 1", "Manhole 2"

Here is the coding i am using:

//fetching the data from the core data

NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
                                          entityForName:@"Input_Details" inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];


request.predicate = [NSPredicate predicateWithFormat:@"rs_Input_project.name = %@", self.projectObject.name];


[request setEntity:entityDescription];
request.resultType = NSDictionaryResultType;

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sewer_No" ascending:YES];
[request setSortDescriptors:@[sortDescriptor]];

NSError *error;

NSArray *fetchedObjects = [moc executeFetchRequest:request error:&error];



 //creating a csv CHCSVWriter
NSOutputStream *output = [NSOutputStream outputStreamToMemory];
CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:output encoding:NSUTF8StringEncoding delimiter:','];

for (id object in fetchedObjects)
{
    if ([object conformsToProtocol:@protocol(NSFastEnumeration)])
    {
        [writer writeLineOfFields:object];

    }
}

[writer closeStream];


NSData *buffer = [output propertyForKey:NSStreamDataWrittenToMemoryStreamKey];

NSString *string = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];

NSLog(@"Length of Buffer:%d Error:%@",[buffer length],[error localizedDescription]);

if ( [MFMailComposeViewController canSendMail] )
{


    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    mailComposer.mailComposeDelegate = self;

    NSData *myData = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"myData csv:%@",myData);
     NSLog(@"string csv:%@",string);

// Fill out the email body text
    NSString *emailBody = @"Sewer_Output";
    [mailComposer setMessageBody:emailBody isHTML:NO];

    //attaching the data and naming it Sewer_Output
    [mailComposer addAttachmentData:myData  mimeType:@"text/cvs" fileName:@"Sewer_Output.csv"];

[self presentModalViewController:mailComposer animated:YES];
}
user1489709
  • 407
  • 4
  • 10
  • Are you sure this array contains NSStrings only? – Shmidt Feb 10 '13 at 08:38
  • You mean to say NSArray *fetchedObjects. No it contains NSString and NSNumber. and "string csv" string gives this output: sewer_No,mh_Up,mh_down sewer_No,mh_Up,mh_down sewer_No,mh_Up,mh_down sewer_No,mh_Up,mh_down sewer_No,mh_Up,mh_down sewer_No,mh_Up,mh_down instead of this it should have this output(values) : 1,MH_01,MH_02 2,MH_02,Mh_03 – user1489709 Feb 10 '13 at 10:50
  • Can you please add to your code content of entity class? – Shmidt Feb 10 '13 at 12:17
  • I think you should write each field of your object separately – Shmidt Feb 10 '13 at 12:20
  • @property (nonatomic, retain) NSNumber * sewer_No; – user1489709 Feb 10 '13 at 12:26

2 Answers2

2
//creating a csv CHCSVWriter
NSOutputStream *output = [NSOutputStream outputStreamToMemory];
CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:output encoding:NSUTF8StringEncoding delimiter:','];
//wrting header name for csv file
[writer writeField:@"Line No"];
[writer writeField:@"Sewer No"];
[writer writeField:@"Manhole Up"];
[writer writeField:@"Manhole Down"];

[writer finishLine];



for (NSManagedObject *object in fetchedObjects)
{
    //getting the data from core data


    int line_no = [[object valueForKey:@"line_no"] intValue];
    int sewer_No = [[object valueForKey:@"sewer_No"] intValue];
    NSString *mh_Up=[object valueForKey:@"mh_Up"];
    NSString *mh_down=[object valueForKey:@"mh_down"];

        //writing that data to writer for csv file

        [writer writeField:[NSString stringWithFormat:@"%i",line_no]];
        [writer writeField:[NSString stringWithFormat:@"%i",sewer_No]];
        [writer writeField:[NSString stringWithFormat:@"%@",mh_Up]];
        [writer writeField:[NSString stringWithFormat:@"%@",mh_down]];

        [writer finishLine]; //finishing the writing of first row

}

[writer closeStream];


NSData *buffer = [output propertyForKey:NSStreamDataWrittenToMemoryStreamKey];

NSString *string = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
//NSLog(@"string = %@",string);

Thanks

user1489709
  • 407
  • 4
  • 10
0
for (ObjectClass *object in fetchedObjects)
{
    if ([object conformsToProtocol:@protocol(NSFastEnumeration)])
    {
        [writer writeField:object.text];
        [writer writeField:[NSString stringWithFormat:@"%i",object.sewer_No.intValue]];
        [writer finishLine];
    }
}
Shmidt
  • 16,436
  • 18
  • 88
  • 136
  • I tried it for (Input_Details *object in fetchedObjects){ if ([object conformsToProtocol:@protocol(NSFastEnumeration)]){ //[writer writeField:object.sewer_No]; //property text not found on object of type 'Input Details *" [writer writeField:[NSString stringWithFormat:@"%i",object.sewer_No.intValue]]; [writer finishLine]; } } gives error "[NSKnownKeysDictionary1 sewer_No]: unrecognized selector sent to instance 0xa196e00" – user1489709 Feb 12 '13 at 11:44
  • Have you created files for class InputDetails? – Shmidt Feb 12 '13 at 15:01
  • I saw you used KVC, hovewer it's easier to create classes for NSManagedObject and use dot notation then. – Shmidt Feb 13 '13 at 19:50