Create csv file from array of data in iOS - objective-c

I want to write data from sql file to csv file. I have collected all data from sql file in an array and using for loop i am appending and writing data to .csv file. but it seems that it shows data in one line only it does not go to new line to create new row.
I have used this for reference.
This is my code :
-(NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"myfile.csv"];
}
- (IBAction)saveAsFileAction:(id)sender {
if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
[[NSFileManager defaultManager] createFileAtPath: [self dataFilePath] contents:nil attributes:nil];
NSLog(#"Route creato");
}
NSString *writeString;
for (int i=0; i<[dataArray count]; i++) {
writeString = [NSString stringWithFormat:#"%#, %#, %#, %#, %0.2f,",[[dataArray objectAtIndex:i]dates],[[dataArray objectAtIndex:i] time],[[dataArray objectAtIndex:i] category],[[dataArray objectAtIndex:i]place],[[dataArray objectAtIndex:i] amount]];
NSLog(#"writeString :%#",writeString);
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForWritingAtPath: [self dataFilePath] ];
//say to handle where's the file fo write
[handle truncateFileAtOffset:[handle seekToEndOfFile]];
//position handle cursor to the end of file
[handle writeData:[writeString dataUsingEncoding:NSUTF8StringEncoding]];
}
}

This only writes one line because you rewrite the file every time you go through your loop. It is best to not writeData on the file until the loop has completed. I would also use an NSMutableString like this:
- (IBAction)saveAsFileAction:(id)sender {
if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
[[NSFileManager defaultManager] createFileAtPath: [self dataFilePath] contents:nil attributes:nil];
NSLog(#"Route creato");
}
NSMutableString *writeString = [NSMutableString stringWithCapacity:0]; //don't worry about the capacity, it will expand as necessary
for (int i=0; i<[dataArray count]; i++) {
writeString = [writeString appendString:[NSString stringWithFormat:#"%#, %#, %#, %#, %0.2f, \n",[[dataArray objectAtIndex:i]dates],[[dataArray objectAtIndex:i] time],[[dataArray objectAtIndex:i] category],[[dataArray objectAtIndex:i]place],[[dataArray objectAtIndex:i] amount]]]; //the \n will put a newline in
}
}
//Moved this stuff out of the loop so that you write the complete string once and only once.
NSLog(#"writeString :%#",writeString);
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForWritingAtPath: [self dataFilePath] ];
//say to handle where's the file fo write
[handle truncateFileAtOffset:[handle seekToEndOfFile]];
//position handle cursor to the end of file
[handle writeData:[writeString dataUsingEncoding:NSUTF8StringEncoding]];
}

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *root = [documentsDir stringByAppendingPathComponent:#"customers.csv"];
NSString *temp;
temp = [NSString stringWithFormat:#"%#", [arrCustomersName objectAtIndex:0]];
for (int i = 1; i < [arrCustomersName count]; i++) {
temp = [temp stringByAppendingFormat:#", %#", [arrCustomersName objectAtIndex:i]];
}
[temp writeToFile:root atomically:YES encoding:NSUTF8StringEncoding error:NULL];

Try this it's working for me ,
If any one want to create .csv file in swift 3
// MARK: CSV file creating
func creatCSV() -> Void {
let fileName = "Tasks.csv"
let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName)
var csvText = "Date,Task Name,Time Started,Time Ended\n"
for task in taskArr {
let newLine = "\(task.date),\(task.name),\(task.startTime),\(task.endTime)\n"
csvText.append(newLine)
}
do {
try csvText.write(to: path!, atomically: true, encoding: String.Encoding.utf8)
} catch {
print("Failed to create file")
print("\(error)")
}
print(path ?? "not found")
}
}
For more details you can refer Detail Answer
Hopes this will help to some one .

// For CSV File :
NSMutableString *stringToWrite = [[NSMutableString alloc] init];
[stringToWrite appendString:[NSString stringWithFormat:#"First Name,Last Name,Full Name,Phone Number, Email,Job, organizationName,Note\n\n"]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for(int i = 0 ;i<[Contact count];i++) {
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"firstName"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"lastName"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact valueForKey:#"userName"] objectAtIndex:i]]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"phoneNumber"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"emailAddress"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"jobTitle"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#,",[[Contact objectAtIndex:i] valueForKey:#"organizationName"] ]];
[stringToWrite appendString:[NSString stringWithFormat:#"%#\n",[[Contact objectAtIndex:i] valueForKey:#"note"] ]];
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentDirectory=[paths objectAtIndex:0];
NSString *strBackupFileLocation = [NSString stringWithFormat:#"%#/%#", documentDirectory,#"ContactList.csv"];
[stringToWrite writeToFile:strBackupFileLocation atomically:YES encoding:NSUTF8StringEncoding error:nil];
});
});

Related

How to attach image in vCard (vcf file) using Objective C?

In my project I need to create and send a vCard (vcf file) that must include an image too. I did everything right except I can not add image to the vCard. I have shared my code below.
- (IBAction)shareButtonPressed:(UIButton *)sender {
NSError *error;
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:#"vCard.vcf"];
[[self vCardRepresentation] writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:#[#"Test", [NSURL fileURLWithPath:filePath]] applicationActivities:nil];
activityVC.excludedActivityTypes = #[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypeMessage, UIActivityTypeCopyToPasteboard];
[self presentViewController:activityVC animated:YES completion:^{
}];
}
- (NSString *)vCardRepresentation
{
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:#"Rokon"], 1.0);
[mutableArray addObject:#"BEGIN:VCARD"];
[mutableArray addObject:#"VERSION:3.0"];
[mutableArray addObject:[NSString stringWithFormat:#"FN:%#", #"Rokon"]];
[mutableArray addObject:[NSString stringWithFormat:#"TEL:%#",#"+8801811536248"]];
[mutableArray addObject:[NSString stringWithFormat:#"PHOTO;BASE64:%#",[imageData base64EncodedDataWithOptions:0]]];
[mutableArray addObject:#"END:VCARD"];
return [mutableArray componentsJoinedByString:#"\n"];
}
- (void)shareContact{
[self emptySandbox];
NSString *contactName = [NSString stringWithFormat:#"%# %#",[Person sharedInstance].firstName, [Person sharedInstance].lastName];
NSError *error;
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.vcf", contactName]];
[[self vCardRepresentation] writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:#[contactName, [NSURL fileURLWithPath:filePath]] applicationActivities:nil];
activityVC.excludedActivityTypes = #[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypeCopyToPasteboard];
[activityVC setValue:contactName forKey:#"subject"];
[self presentViewController:activityVC animated:YES completion:^{
}];
}
- (NSString *)vCardRepresentation
{
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
NSData *imageData = UIImageJPEGRepresentation([Person sharedInstance].profileImage, 1.0);
[mutableArray addObject:#"BEGIN:VCARD"];
[mutableArray addObject:#"VERSION:3.0"];
[mutableArray addObject:[NSString stringWithFormat:#"FN:%#", [NSString stringWithFormat:#"%#%#", [Person sharedInstance].firstName, [Person sharedInstance].lastName]]];
[mutableArray addObject:[NSString stringWithFormat:#"TEL:%#",[Person sharedInstance].phone]];
[mutableArray addObject:[NSString stringWithFormat:#"email:%#", [Person sharedInstance].email]];
[mutableArray addObject:[NSString stringWithFormat:#"PHOTO;BASE64;ENCODING=b;TYPE=JPEG:%#",[imageData base64EncodedStringWithOptions:0]]];
[mutableArray addObject:#"END:VCARD"];
return [mutableArray componentsJoinedByString:#"\n"];
}
-(void)emptySandbox
{
NSFileManager *fileMgr = [[NSFileManager alloc] init];
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *files = [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:nil];
while (files.count > 0) {
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *directoryContents = [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error];
if (error == nil) {
for (NSString *path in directoryContents) {
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:path];
BOOL removeSuccess = [fileMgr removeItemAtPath:fullPath error:&error];
files = [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:nil];
if (!removeSuccess) {
// Error
}
}
} else {
// Error
}
}
}

Mac os x writeToFile not working using xcode5

I'm trying to modify a plist and saving the changes but it doesn't work:
here is my code:
NSString *myPath = [[NSBundle mainBundle] pathForResource:#"myPlist" ofType:#"plist"];
NSMutableDictionary *plistDict;
NSMutableArray *array = [[NSMutableArray alloc]initWithArray:[plistDict objectForKey:#"$objects"]];
for (int i =0 ; i <array.count; i++)
{
if ([[array objectAtIndex:i] isKindOfClass:[NSString class]])
{
if ([[array objectAtIndex:i] isEqualToString:#"myString"])
{
[[plistDict objectForKey:#"$objects"]replaceObjectAtIndex:i withObject:#"newString"];
}
}
}
NSString *root = #"/Users/myUser/Desktop/newPlist.plist";
[plistDict writeToFile:root atomically:YES];
the dictionary of the content is been modify and I don't have any errors but the file is never been created in the path. Any of you know what I'm doing wrong? or how can I fixed?
I suspect that you are writing to a Sandboxed location. Not actually to the users directory.
Refer the below code:-
NSMutableDictionary *plistDict=//assuming your data
NSString *root = #"/Users/home/Desktop/newPlist.plist";
if (![[NSFileManager defaultManager]fileExistsAtPath:root])//checking fileexist or not
{
//if not exist creating the same
[[NSFileManager defaultManager]createFileAtPath:root contents:nil attributes:nil];
[plistDict writeToFile:root atomically:YES];
}
else
{
[plistDict writeToFile:root atomically:YES];
}

Failed to generate csv file

-(void)generateCSV
{
NSFileManager *filemgr = [NSFileManager defaultManager];
[filemgr createFileAtPath:#"test.csv" contents:nil attributes: nil];
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:#"test.csv"];
NSLog (#"why null %#", file);
[file seekToEndOfFile];
NSLog(#"%#", file);
surveyarray = [db retrieveSurvey];
for(int i = -1; i < surveyarray.count; i++)
{
if(i == -1)
{
NSString *str = [NSString stringWithFormat: #"No, CreatedDate, Question1, Question2, Question3, Comment\n"];
[file writeData: [str dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
}
else
{
survey = [surveyarray objectAtIndex:i];
NSString *str = [NSString stringWithFormat: #"%d, %#, %#, %#, %#, %#\n", i, survey.createddate, survey.question1, survey.question2, survey.question3, survey.comment];
[file writeData: [str dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
}
}
[file closeFile];
/*CHCSVWriter * csvWriter = [[CHCSVWriter alloc] initWithCSVFile:fullPath atomic:NO];
NSInteger numberOfColumns = 5;
for (NSInteger currentIndex = 0; currentIndex < [surveyarray count]; currentIndex++)
{
id field = [surveyarray objectAtIndex:currentIndex];
[csvWriter writeField:field];
if ((currentIndex % numberOfColumns) == (numberOfColumns - 1))
{
[csvWriter writeLine];
}
}
[csvWriter release];*/
}
I had log the file and return (null)
log output
2012-12-19 14:46:55.853 OCBC[6725:907] (null)
2012-12-19 14:46:55.860 OCBC[6725:907] 2012-12-19 14:14:31
2012-12-19 14:46:55.862 OCBC[6725:907] Interview
2012-12-19 14:46:55.863 OCBC[6725:907] Visitor
2012-12-19 14:46:55.865 OCBC[6725:907] Meet Expectation
2012-12-19 14:46:55.866 OCBC[6725:907] N/A
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *filePath = [documentsDir stringByAppendingPathComponent:#”test.csv”];
try to pass the filePath to your method

WriteData causes sigabrt error

I want to read a file (hello.in) and to write it to another file line by line.
I write the below method and when I run it I get sigabrt error.
I would love to get answer.
-(void) saveAsLineLine: (NSString*) fileName
{
NSString *filePath;
filePath = [NSString stringWithFormat:#"%#%#", pathdir, #"hello.in"];
// reading the file
NSString *entireFileInString = [NSString stringWithContentsOfFile:filePath encoding:(NSUTF8StringEncoding) error:nil];
// each line, adjust character for line endings
NSArray *lines = [entireFileInString componentsSeparatedByString:#"\n"];
filePath = [NSString stringWithFormat:#"%#%#", pathdir, fileName];
// create a file
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
// open the file for writeing
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:filePath];
// write line by line
for (NSData *line in lines)
{
NSLog (#"line: %#\n", line);
[fh seekToEndOfFile];
[fh writeData: line]; // THE BUG IS HERE !!!!!!!!
// #try {
// [fh writeData: line];
//
// }
// #catch (NSException *exception) {
// NSLog(#"%#",[exception description]);
// }
}
[fh closeFile];
}
The NSArray lines holds instances of NSString, not NSData, right?
If you want to write data to file...
[lines enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSData *lineData = [obj dataUsingEncoding:NSUTF8StringEncoding];
[fh seekToEndOfFile];
[fh writeData:lineData];
}];

NSFileHandle fileHandleForWritingAtPath: return null!

my iPad app has a small download facility, for which I want to append the data using an NSFileHandle. The problem is the creation call only returns null file handles. What could be the problem? Here is the three lines of code that are supposed to create my file handle:
NSString *applicationDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
self.finalPath = [applicationDocumentsDirectory stringByAppendingPathComponent: self.fileName];
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:self.finalPath];
I checked the file path, and I could see nothing wrong.
TYIA
fileHandleForWritingAtPath is not a “creation” call. The documentation explicitly states: “Return Value: The initialized file handle, or nil if no file exists at path” (emphasis added). If you wish to create the file if it does not exist, you’d have to use something like this:
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:self.finalPath];
if(output == nil) {
[[NSFileManager defaultManager] createFileAtPath:self.finalPath contents:nil attributes:nil];
output = [NSFileHandle fileHandleForWritingAtPath:self.finalPath];
}
If you want to append to the file if it already exists, use something like [output seekToEndOfFile]. Your complete code would then look as follows:
NSString *applicationDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
self.finalPath = [applicationDocumentsDirectory stringByAppendingPathComponent: self.fileName];
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:self.finalPath];
if(output == nil) {
[[NSFileManager defaultManager] createFileAtPath:self.finalPath contents:nil attributes:nil];
output = [NSFileHandle fileHandleForWritingAtPath:self.finalPath];
} else {
[output seekToEndOfFile];
}
Get documents directory path
+(NSURL *)getDocumentsDirectoryPath
{
return [[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]lastObject];
}
Save text to end of the file
if file doesnt exist create it and write data
+(void)saveText:(NSString *)textTobeSaved atPath:(NSString*)fileName
{
NSString *filePath = [NSString stringWithFormat:#"%#.text",fileName];
NSString *path = [[self getDocumentsDirectoryPath].path
stringByAppendingPathComponent:filePath];
NSFileHandle *fileHandler = [NSFileHandle fileHandleForWritingAtPath:path];
if(fileHandler == nil) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
fileHandler = [NSFileHandle fileHandleForWritingAtPath:path];
} else {
textTobeSaved = [NSString stringWithFormat:#"\n-----------------------\n %#",textTobeSaved];
[fileHandler seekToEndOfFile];
}
[fileHandler writeData:[textTobeSaved dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandler closeFile];
}
get text from file with specified filename
+(NSString *)getTextFromFilePath:(NSString *)fileName
{
NSString *filePath = [NSString stringWithFormat:#"%#.text",fileName];
NSString *path = [[self getDocumentsDirectoryPath].path
stringByAppendingPathComponent:filePath];
NSLog(#"%#",path);
if(path!=nil)
{
NSString *savedString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
return savedString;
}else{
return #"";
}
}
Delete file
+(void)deleteFile:(NSString *)fileName
{
NSString *filePath = [NSString stringWithFormat:#"%#.text",fileName];
NSString *path = [[self getDocumentsDirectoryPath].path
stringByAppendingPathComponent:filePath];
NSFileHandle *fileHandler = [NSFileHandle fileHandleForWritingAtPath:path];
if(fileHandler != nil) {
[[NSFileManager defaultManager]removeItemAtPath:path error:nil];
}
}