Skip to content

Instantly share code, notes, and snippets.

@beccadax
Created September 26, 2013 11:29
Show Gist options
  • Save beccadax/6712885 to your computer and use it in GitHub Desktop.
Save beccadax/6712885 to your computer and use it in GitHub Desktop.
NSFileWrapper is really convenient, but has a lot of pain points. Here's my design for a replacement.
// There's a lot that bothers me about NSFileWrappers:
// * Directories are mutable, but regular files and symlinks aren't.
// * You can't change from one type to another.
// * ...but the -readFromURL:... method can violate both of these rules. Probably.
// * Wrappers include a .filename, but this is only relevant to their containing folders.
// * Wrappers include a .preferredFilename, but this is only relevant to the folder they're being added to, and doesn't matter after being added.
// * There's no way to replace a file wrapper in a directory, except by removing the old one and then adding the new one.
// Here's how I would design a file wrapper replacement.
typedef NS_ENUM(NSUInteger, GBSFileWrapperType) {
GBSFileWrapperTypeUnspecified, // contents is nil, -writeToURL:... fails
GBSFileWrapperTypeRegularFile, // contents is an NSData
GBSFileWrapperTypeDirectory, // contents is an NSDictionary
GBSFileWrapperTypeSymbolicLink // contents is an NSURL
};
// I'm not going to specify the reading/writing options, because they don't really matter that much.
@interface GBSFileWrapper : NSObject <NSCopying, NSMutableCopying, NSCoding>
// Designated initializer.
- (id)initWithContents:(id)contents resourceValues:(NSDictionary*)resourceValues;
// This would probably actually be implemented with a private subclass to allow for lazy loading.
- (id)initWithContentsOfURL:(NSURL*)URL options:(GBSFileWrapperReadingOptions)options error:(NSError**)error;
@property (readonly) GBSFileWrapperType type;
@property (readonly) id contents;
@property (readonly) NSDictionary * resourceValues; // Uses NSURL constants
- (BOOL)writeToURL:(NSURL*)URL options:(GBSFileWrapperWritingOptions)options error:(NSError**)error;
@end
@interface GBSFileWrapper (SerializedRepresentation)
- (id)initWithSerializedRepresentation:(NSData*)data;
@property NSData * serializedRepresentation;
@end
@implementation GBSMutableFileWrapper : GBSFileWrapper
@property (readwrite) id contents;
@property (readwrite) NSDictionary * resourceValues;
// These only work on directories
- (void)setChild:(GBSFileWrapper*)child forName:(NSString*)name;
- (void)removeChildForName:(NSString*)name;
- (NSString*)addChild:(GBSFileWrapper*)child withPreferredName:(NSString*)preferredName;
- (BOOL)readFromURL:(NSURL*)URL options:(GBSFileWrapperReadingOptions)options error:(NSError**)error;
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment