I am writing a text-editor and I would need to store a few pieces of information (generally just a few strings; the storage needn't be particularly durable) with each file the app saves (without that being part of the text-file as other apps might read it and the info is only specific to my app).
How would I go about this?
More info: I have a NSDocument set up and I would like to simply store a NSString instance variable as a per file meta-datum. Based on the answers below I've come up with this, which is currently buggy and causes the program to crash on startup:
#import <sys/xattr.h>
@interface MyDocument : NSDocument {
NSString *metadatum;
}
@implementation MyDocument
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)type error:(NSError **)err
{
BOOL output = [super writeToURL:url ofType:type error:err];
if(!setxattr([[url path] cStringUsingEncoding:NSUTF8StringEncoding],
"eu.gampleman.xattrs.style",
[metadatum cStringUsingEncoding:NSUTF8StringEncoding],
sizeof(char) * [styleName length], 0, 0))
{
NSLog(@"Write failure");
}
return output;
}
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)type error:(NSError **)err {
char *output;
ssize_t bytes = getxattr([[url path] cStringUsingEncoding:NSUTF8StringEncoding],
"eu.gampleman.xattrs.style", &output, 1024, 0, 0);
if (bytes > 0) {
metadatum = [[NSString alloc] initWithBytes:output length:bytes
encoding:NSUTF8StringEncoding]; // <- crashes here with "EXC_BAD_ACCESS"
}
return [super readFromURL:url ofType:type error: err];
}
// ...
// fairly standard -dataOfType:error: and
// -readFromData:ofType:error: implementations
PS: If your answer is really good (with sample code, etc.), I will award a 100rep bounty.
If you want to add metadata support for text files, say, then all you have to do is scroll the left-hand “File Extensions” list, select the TXT file type, and click “Add File Meta Handler”.
No. There is no such data for a . txt file.
The first option is to put the metadata in a central location for all data. The second option was to put the metadata with the data itself. The first option is one that is used by many search or archive systems. The idea is fairly simple—gather metadata about a specific file and store it, typically in a database.
In addition to seven default metadata fields you can easily add your own custom metadata fields as well. You can do so by applying the custom metadata fields on folder level, so that the same fields are automatically assigned to all files in that folder — and optionally its sub folders.
Use extended attributes. See setxattr().
Here's a sample call to write a string:
NSData* encodedString = [theString dataUsingEncoding:NSUTF8StringEncoding];
int rc = setxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", [encodedString bytes], [encodedString length], 0, 0);
if (rc)
/* handle error */;
To read a string:
ssize_t len = getxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", NULL, 0, 0, 0);
if (len < 0)
/* handle error */;
NSMutableData* data = [NSMutableData dataWithLength:len];
len = getxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", [data mutableBytes], len, 0, 0);
NSString* string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
PS: Don't you have to set the bounty on the question before it's answered?
There are several places to store this kind of information on Mac. The most simple, of course, is to store it in your own separate metadata database. Of course there are challenges if the file moves. Since 10.6, however, you can use Bookmarks to address this problem. A Bookmark (see NSURL) allows you to keep a reference to a file even if it is moved (even across application restarts). Prior to 10.6 there was the Alias Manager, but it couldn't create new aliases; just read ones that Finder created.
The next common solution is to create metadata files. So if I have foo.txt
, then you create a sibling .foo.txt.metadata
to hold the extra info. Several trade-offs there if the files can be moved around.
Next is Spotlight, which can be used to attach arbitrary information to files. The actual tool here is xattr (see the man pages for setxattr
and its relatives). These basically absorb several things that used to be done with Resource Forks (except xattr is supposed to just be metadata).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With