Re: Saving data to a file
Re: Saving data to a file
- Subject: Re: Saving data to a file
- From: Lucas Haley <email@hidden>
- Date: Fri, 14 Mar 2003 17:26:16 -0800
Ian & Ron --
This is about what I just implemented in my app, except that I am
deriving all of my classes from one class, DMTObject, that uses the
objective-c runtime to find all of the instance variables, and returns
an array. This can then be used to assemble the dictionary -- without
having to add any code whatsoever to subclasses.
I think this is pretty cool. By writing this into _one class_, and
adding another method to output xml, I gave every class the ability to
output human-readable (and cross-platform) xml. Here are some snippets,
cut up a bit so it might not make total coding sense:
+ (NSArray *)instanceVariables
{
Class theClass = [self class];
NSMutableArray *resultArray = [[[NSMutableArray alloc] init]
autorelease];
struct objc_ivar_list *iList = theClass->ivars;
if (iList)
{
const int numberOfInstanceVariables = iList->ivar_count;
int i;
NSLog(@"%@", [self className]);
// get super?
if (![[self superclass] isEqual:[NSObject class]])
{
[resultArray addObjectsFromArray:[[self superclass]
instanceVariables]];
}
for (i = 0; i < numberOfInstanceVariables; i++)
{
Ivar currentInstanceVariable = &iList->ivar_list[i];
NSString *result = [NSString stringWithFormat:@"%s",
currentInstanceVariable->ivar_name];
[resultArray addObject:result];
}
}
return [NSArray arrayWithArray:resultArray];
}
- (NSString *)xmlString
{
NSArray *instanceVariablesArray = [[self class] instanceVariables];
NSEnumerator *enumerator = [instanceVariablesArray
objectEnumerator];
NSString *cs;
NSMutableString *result = [[[NSMutableString alloc] init]
autorelease];
NSLog(@"%@:xmlString\n", [self className]);
[result appendFormat:@"<%@>", [self class]];
while (cs = [enumerator nextObject])
{
NSMutableString *currentKey = [cs mutableCopy];
[currentKey replaceOccurrencesOfString:@"_" withString:@""
options:NSCaseInsensitiveSearch range:NSMakeRange(0, 1)];
NSString *currentValue = [[self valueForKey:currentKey] xmlString];
[result appendFormat:@"<%@>", currentKey];
[result appendFormat:@"%@", currentValue];
[result appendFormat:@"</%@>", currentKey];
}
[result appendFormat:@"</%@>", [self class]];
// [result autorelease];
return [NSString stringWithString:result];
}
- (id)initWithDictionary:(NSDictionary *)dict
{
if (self = [super init])
{
// iterate through dictionary
NSEnumerator *enumerator = [dict keyEnumerator];
id key;
while (key = [enumerator nextObject])
{
id value = [dict objectForKey:key];
if (value)
{
// check if we can respond to the selector
if ([self respondsToSelector:@selector(key)])
{
// we can now assign the value
[self takeValue:value forKey:key];
} else {
// the damn object will not respond to that key!
}
}
}
}
return self;
}
@end
I hope this helps! Maybe it will spark some ideas...
-Lucas
On Friday, March 14, 2003, at 02:36 PM, Mondragon, Ian wrote:
ron,
if you'd like a human readable archive for an object, here's what i
tend to
do with objects:
1. implement a -dictionaryRepresentation method that spits out a
dictionary
containing all pertinent information about the object
2. implement an -initFromDictionary: method that allows you to
initialize an
object from a dictionary (that you'd read in from such an archive)
3. wrap these methods into read/write methods for files.
4. use the standard NSDictionary methods & go nuts
below is a really quick example WITHOUT ERROR CHECKING/accessor
methods/etc., but it should give you an idea. the nice thing about
doing
things this way (i.e. using the standard foundation objects) is that
it's
VERY extensible. your milage may vary, though.
for non-human-readable archives, check out the "Archiving and
Serialization"
section in PB's Cocoa help.
hope this gets you going...
- ian
--- snip ---
@interface SaveThisObject : NSObject
{
NSString *name;
NSArray *array;
}
- initFromDictionary:(NSDictionary *)aDictionary;
- initFromFile:(NSString *)filename;
- (NSDictionary *)dictionaryRepresentation;
- (BOOL)saveToFile:(NSString *)filename;
// other methods, of course, go here
@end
--- snip ---
NSString *_NameString = @"name";
NSString *_ArrayString = @"array";
@implementation SaveThisObject
- initFromDictionary:(NSDictionary *)aDictionary
{
if ((self = [super init]))
{
// PLEASE put error checking here - this is just a quicky
[self setName:[aDictionary objectForKey:_NameString]];
[self setArray:[aDictionary objectForKey:_ArrayString]];
return self;
}
return nil;
}
- initFromFile:(NSString *)filename
{
return [self initFromDictionary:[NSDictionary
dictionaryWithContentsOfFile:filename]];
}
- (NSDictionary *)dictionaryRepresentation
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:name forKey:_NameString];
[dict setObject:array forKey:_ArrayString];
return dict;
}
- (BOOL)saveToFile:(NSString *)filename
{
return [[self dictionaryRepresentation] writeToFile:filename
atomically:YES];
}
@end
--- snip ---
-----Original Message-----
From: Ron Phillips [SMTP:email@hidden]
Sent: Friday, March 14, 2003 3:48 PM
To: email@hidden
Subject: Saving data to a file
I have scoured the cocoa-dev archives, web sites and books and still
am
confused on how best to write data to a file from a non-document-based
application. An XML format is fine, human-readable is not required.
I
have a collection of arrays, ints, strings, and BOOLs. What
preparation is needed for a property list? Chris Kane indicated that
archiving is not compatible with plists and writeToFile:atomically:.
That's cool, so do I just *somehow* wrap up my high-level object into
an NSData object and do the write? If so, what's the best approach to
do that? Is encoding still needed?
Thanks in advance and best regards,
Ron
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
----
If you ever teach a yodeling class, probably the hardest thing is to
keep the students from just trying to yodel right off. You see, we
build to that.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.