stop files from truncating objective C? - iphone

I am trying to write some data to a file in iphone sdk....I am using a for statement to write to explain the situation better I have some code:
for(int i = 0;i < 11;i++){
NSString *myFile = [documentsDirectory stringByAppendingPathComponent:#"hello.txt"];
[i writeToFile: myFile atomically:NO encoding:NSUTF8StringEncoding error:NULL];
}
now I expect 12345678910 to written in the file but only 10 is written in it which means file is being trncated everytime I write to file..so my question is what can I do to write 1 to 10 WITHOUT puttting everything in a string because I have alot of data..
thanks

The SDK documentation says this about -writeToFile:atomically:encoding:error: This method overwrites any existing file at path.
That method is intended for dumping a string out to a file. For your purposes, you can either build up a string, or open a file with [NSFileHandle fileHandleForWritingAtPath]:
NSString *myFile = [documentsDirectory stringByAppendingPathComponent:#"hello.txt"];
NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:myFile];
for(int i = 0; i <= 10; i++) {
NSString *dataString = [NSString stringWithFormat:#"%i", i];
[file writeData:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
}
[file closeFile];

If you're trying to write a series of integers to a file, I would go about it like this:
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:FILE_PATH];
for(int i=0; i<11; i++)
{
NSString *str = [NSString stringWithFormat:#"%d",i];
[fileHandle writeData:[str dataUsingEncoding:NSUTF8StringEncoding]];
}
[fileHandle closeFile];

Related

Saving in NSDocumentDirectory uniquely

Hi Im really having a hard time saving in my NSDocumentDirectory.Im using AGImagePickerby the way. Yes I was able to save this in NSDocumentDirectory. But how to save them uniquely ( in terms of their own then converting their names into oneSlotImages) or save them with their unique IDs then load them back. Sorry Im kinda new to this UIImagePickerControllerMediaURL thing., I think that would be my solution to my other problem for not overlaping them when saving. How to save this using their unique ID, or UIImagePickerControllerMediaURL.
for (int i = 0; i < info.count; i++) {
NSLog(#"%#", [info objectAtIndex:i]);
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"oneSlotImages%d.png", i]];
ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
//----resize the images
image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:YES];
Thanks for the help. Much Appreciated.
You could always keep a list of used names and do something like this
int i = 1;
while([listOfUsedNames containsObject:nextAvailableTile]) {
nextAvailableTitle = [kDefaultImageName stringByAppendingFormat:#" %d", i];
i++;
}
// found an unused name
The URL for each image is unique right? So we can make use of this. Convert the URL into MD5 string (which form a unique identifier for each image). And save with that name (like "MD5string.png").
Why can't we use this?
Hope this helps you.
For converting to MD5, please create a file named NSString+MD5.h and put the code
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#interface NSString(MD5)
- (NSString *)MD5;
#end
in it.
Then in the NSString+MD5.m,
#import "NSString+MD5.h"
#implementation NSString(MD5)
- (NSString*)MD5
{
const char *ptr = [self UTF8String];
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(ptr, strlen(ptr), md5Buffer);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x",md5Buffer[i]];
return output;
}
#end
Import the NSString+MD5.h class where ever you want to use the MD5 function with normal NSString object.
In you code if you have the UIImagePickerControllerMediaURL string, since it is unique for every file you can convert in to MD5 String like
NSString *imgURL = [NSString stringWithString: UIImagePickerControllerMediaURL];
NSString *MD5String = [imgURL MD5];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", MD5String]];
Use that path to save your image file.
On Loading,
Convert the UIImagePickerControllerMediaURL into MD5 and check in the Documents directory for the file
// In this the UIImagePickerControllerMediaURL is the URL of media file to load
NSString *imgURL = [NSString stringWithString: UIImagePickerControllerMediaURL];
NSString *MD5String = [imgURL MD5];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", MD5String]];
Then do the checking with the fileExistsAtPath method of NSFileManager and if exists then load the file from the path. Thats it.
Note: For this you want to keep the UIImagePickerControllerMediaURL of the images you saved in documents directory locally somewhere in your app (In DB or NSUserDefaults) for make use of then at the time of loading.
Try this:
NSMutableString *imageName = [[[NSMutableString alloc] initWithCapacity:0] autorelease];
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
[imageName appendString:NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID))];
CFRelease(theUUID);
}
[imageName appendString:#".png"];

How to search a word from the .txt file that has been included in the project in xcode

I have included a .txt file in my project and i have to find a keyword from that file by entering the keyword in the search bar. Help me with the piece of code for searching the keyword that is present in the file.
Try that
//Get the contents of the file
NSString *contentString = [NSString stringWithContentOfFile:<i>path/to/your/file.txt</i> encoding:<i>textEncoding<i> error:<i>&error</i>];
if (!error) {
NSRange range = [contentString rangeOfString:<i>yourKeyword</i>];
if (theRange.location != NSNotFound)
//do whatever you want
}
NB : this will work as long as your text file is not "too big". If you have to work with bigger files, take a look at NSInputStream to only parse chunks of the file
Try this:
-(void)searchWord:(NSString *)wordToBeSearched{
NSString* path = [[NSBundle mainBundle] pathForResource:#"wordFile"
ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSString *delimiter = #"\n";
NSArray *items = [content componentsSeparatedByString:delimiter];
NSString *character = #" ";
BOOL isContain = NO;
for (NSString *wordToBeSearched in items) {
isContain = ([string rangeOfString:wordToBeSearched].location != NSNotFound);
}
return isContain;
}
You can go here for more details

locate byte in pdf file and read line

I try to read pdf file. I want to use this function
databuffer = [file readDataOfLength : 7] but i want read all the byte in the line .
It mean I use seekToFileOffset to find the byte but I want read the line.
NSMutableArray *nameArray = [[NSMutableArray alloc] initWithObjects:nil];
NSMutableArray *nameArrayDict = [[NSMutableArray alloc] initWithObjects:nil];
NSString *path = [[NSBundle mainBundle] pathForResource:#"testpdf" ofType:#"pdf"];
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:nil];
int var=[[nameArray objectAtIndex:[nameArray count]-2] intValue];
NSFileHandle *file;
NSData *databuffer;
file = [NSFileHandle fileHandleForReadingAtPath: appFile];
int i=0;
while (file!=nil ) {
[file seekToFileOffset: var+i];
databuffer = [file readDataOfLength : 7];
NSString* aStr;
aStr = [[NSString alloc] initWithData: databuffer encoding:NSASCIIStringEncoding];
NSLog(#"%#",aStr);
i=i+[databuffer length];
}
now i try your solution but i can't show nothing!!!
CGPDFPageRef page = CGPDFDocumentGetPage (myDocument, 1);// 2
CGPDFDictionaryRef d;
d = CGPDFPageGetDictionary(page);
CGPDFScannerRef myScanner;
CGPDFOperatorTableRef myTable;
myTable = CGPDFOperatorTableCreate();
CGPDFContentStreamRef myContentStream = CGPDFContentStreamCreateWithPage (page);// 3
myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);// 4
CGPDFScannerScan (myScanner);// 5
CGPDFOperatorTableSetCallback(myTable, "BT", &op_BT);//Begin text object
CGPDFOperatorTableSetCallback(myTable, "ET", &op_ET);//End text object
CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);
I recommend not to parse your pdf in a way you like to do it.
Try to use CGPDFScanner (docs here)
As JeremyP says: lot's of zlib compressed stuff is in a PDF file. Do search for end of lines.
Use CGPDFScanner to extract font maps, images, etc.
But is not that easy. I can tell you. :)

Problem with CGImageDestination and file naming

I am capturing images from the camera, using AVCapture as I have need of speed and the standard kit stuff is way too slow.
I have problem whereby the file that is being output (an animated GIF) is having it's file name mangles by the CGImageDestination functions...
When I output the NSURL (cast to a CFURLRef) to the log I get the path/filename I intended:
2011-09-04 20:40:25.914 Mover[3558:707] Path as string:.../Documents/91B2C5E8-F925-47F3-B539-15185F640828-3558-000003327A227485.gif
However, once the file is created and saved it actually lists the filename as this:
2011-09-04 20:40:25.960 Mover[3558:707] file: .91B2C5E8-F925-47F3-B539-15185F640828-3558-000003327A227485.gif-TtNT
See the difference? the period at the start and the 4 character suffix?
Whats really wierd is that it doesn't always do it, about 40% of the time it works OK. However it's preventing the code working further down the line where I'm listing them with previews in a table view.
Does anyone know why and how to stop it doing this?
Here's the code:
- (void)exportAnimatedGif{
NSString *guidPath = [[NSProcessInfo processInfo] globallyUniqueString];
NSString *tmpPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:guidPath];
NSString *path = [tmpPath stringByAppendingPathExtension:#"gif"];
NSLog(#"Path as string:%#", path);
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], kUTTypeGIF, [captureArray count], NULL);
NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:testDisplay3.displayValue] forKey:(NSString *)kCGImagePropertyGIFDelayTime]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:2], (NSString *)kCGImagePropertyGIFLoopCount,
[NSNumber numberWithFloat:testDisplay3.displayValue], (NSString*)kCGImagePropertyGIFDelayTime,
[NSNumber numberWithFloat:testDisplay3.displayValue], (NSString*)kCGImagePropertyGIFUnclampedDelayTime,
nil]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
for (int ii = 0; ii < [captureArray count]; ii++)
{
UIImage *tmpImg = [[UIImage alloc] init];
tmpImg = [captureArray objectAtIndex:ii];
CGImageDestinationAddImage(destination, tmpImg.CGImage, (CFDictionaryRef)frameProperties);
}
CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
CGImageDestinationFinalize(destination);
CFRelease(destination);
//TEST OUTPUT GENERATED FILES
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] error:nil];
for (int xx = 0; xx < [contents count]; xx++)
{
NSLog(#"file: %#", [contents objectAtIndex:xx]);
}
//END TEST CODE
[captureArray removeAllObjects];
}
AFAIK this is a temporary file that CGImageDestinationFinalize makes, the reason you see them is that CGImageDestinationFinalize failed. I think that if you check the file sizes you'll see that the ones with mangled names have a file size of 0.
I started check for succes after I got these files :)
bool success = CGImageDestinationFinalize(destination);
CFRelease(destination);
if (success) {
NSLog(#"animated GIF file created at %#", path);
} else {
NSLog(#"failed to create gif at %#", path);
}

how to write .csv file from function?

Hey Friends i got all contacts detail of my iphone by using this function ..
-(void)collectContacts
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
//NSLog(#" the Name %#%",people);
for(int i = 0;i<ABAddressBookGetPersonCount(addressBook);i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex(people, i);
// Get First name, Last name, Prefix, Suffix, Job title
NSString *firstName = (NSString *)ABRecordCopyValue(ref,kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(ref,kABPersonLastNameProperty);
NSString *prefix = (NSString *)ABRecordCopyValue(ref,kABPersonPrefixProperty);
NSString *suffix = (NSString *)ABRecordCopyValue(ref,kABPersonSuffixProperty);
NSString *jobTitle = (NSString *)ABRecordCopyValue(ref,kABPersonJobTitleProperty);
NSLog(#" the phoneType %#%",firstName);
NSLog(#" the phoneType %#%",lastName);
ABMultiValueRef phones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
NSString *phoneLabel =(NSString*) ABAddressBookCopyLocalizedLabel (ABMultiValueCopyLabelAtIndex(phones, j));
NSString *phoneNumber = (NSString *)phoneNumberRef;
NSLog(#" the phoneType %#%",phoneLabel);
NSLog(#" the phoneNumber %#%",phoneNumber);
}
CFStringRef address;
CFStringRef label;
ABMutableMultiValueRef multi = ABRecordCopyValue(ref, kABPersonAddressProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++)
{
label = ABMultiValueCopyLabelAtIndex(multi, i);
CFStringRef readableLabel = ABAddressBookCopyLocalizedLabel(label);
NSLog(#" Lable %#%",readableLabel);
address = ABMultiValueCopyValueAtIndex(multi, i);
NSLog(#" Address %#%",address);
CFRelease(address);
CFRelease(label);
}
ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
for(CFIndex idx = 0; idx < ABMultiValueGetCount(emails); idx++)
{
CFStringRef emailRef = ABMultiValueCopyValueAtIndex(emails, idx);
NSString *strLbl = (NSString*) ABAddressBookCopyLocalizedLabel (ABMultiValueCopyLabelAtIndex (emails, idx));
NSLog(#" Email Lable %#%",strLbl);
NSString *strEmail_old = (NSString*)emailRef;
NSLog(#" Email-Id %#%",strEmail_old);
//[[strEmail_old componentsJoinedByString:#","] writeToFile:#"components.csv" atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
}
//[[ContactsText componentsJoinedByString:#","] writeToFile:#"components.csv" atomically:YES encoding:NSUTF8StringEncoding error:NULL];
// NSLog(#" Data in the .CSV file = %#%",ContactsText);
}
'
Now i want to make .csv file from this function's output .. and m getting all data in NSLog . I juat want to write .csv file from that data .. Can anyone help me in that ?? Data coming are proper but .csv file not gonna written ...Thanks
Assuming you will have all the data in "ContactsText", try following code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* savePath = [paths objectAtIndex:0];
savePath = [savePath stringByAppendingPathComponent:#"components.csv"];
[[ContactsText componentsJoinedByString:#","] writeToFile:savePath atomically:YES encoding:NSUTF8StringEncoding error:NULL];
Remember that you cannot just save "components.csv" file. You have to save the file in documents folder only.
There are many Open Source extensions that add csv support to arrays. For example CHCSVParser which is available on GitHub.
Notice that your data may contain characters that require special treatment - in the case of a CSV file most notably the comma itself. If there is a comma in the string you write out, you should put double quotes around that field. In that case, if there is already a double quote in the string, you need to escape that, too.
I would suggest that you use the CHCSVParser from Dave DeLong, you can find it here: http://davedelong.com/portfolio
It is worth the trouble to import a good third-party framework to make sure edge cases are handled correctly.