Wednesday, August 18, 2010

NSString appendToFile:usingEncoding:

Somewhat frequently I find myself looking in Apple's documentation for a method that I'm sure exists but doesn't show up when I search using the Documentation Viewer in Xcode. Usually in that case, the method does actually exist, but it's not from Apple. Nine out of ten times it means I've got a category method I've used so many times that I've forgotten Apple didn't provide it. The other one out of ten, it's just an indication that I'm slowly growing senile.

When this happens, I try to post the category methods because I figure if I've used the method enough over the years that I though it came from Apple, then other people might be able to use it.

One bit of functionality that I've always been surprised isn't in NSString class is the ability to append the contents of a string onto an existing file. There are methods for creating or replacing a file with the contents of a string, so why not to append the contents onto an existing file? It's a fairly common and very useful task. I've used it for creating application logs, and for other situations where I need to create large files that wouldn't be practical to keep in memory. This is especially nice to have on iOS given the lack of virtual memory.

Here's the category method I use for this. I dug this up yesterday from an older project after searching for it in Apple's documentation. I had to update it a little (it was old enough that it used the old deprecated cString methods.

#import <Foundation/Foundation.h>

@interface NSString(MCFileAppend)
- (BOOL)appendToFile:(NSString *)path usingEncoding:(NSStringEncoding)encoding;
@end


@implementation NSString(MCFileAppend)
- (BOOL)appendToFile:(NSString *)path usingEncoding:(NSStringEncoding)encoding
{
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:path];
if (fh == nil)
return [self writeToFile:path atomically:YES encoding:encoding error:nil];

[fh truncateFileAtOffset:[fh seekToEndOfFile]];
NSData *encoded = [self dataUsingEncoding:encoding];

if (encoded == nil) return NO;

[fh writeData:encoded];
return YES;
}

@end

No comments:

Post a Comment