0

I have been working on this problem for a while, I have an app running on the mac, it has co-ordinate data stored in a struct like this:

struct xyz {
  float x;
  float y;
  float z;
};

struct xy {
  float x;
  float y;
};

struct object {
  struct xyz *myXYZ;
  struct xy *myXY;
};

This all works as expected, then I add the struct into NSData like so:

struct object anInitialTestStruct;
NSMutableData *myTestDataOut = [NSMutableData dataWithBytes:&anInitialTestStruct length:64 freeWhenDone:NO];
BOOL good = [myTestDataOut writeToFile:[NSString stringWithFormat:@"%@/filename.dat", docsDirectory] atomically:YES];

This works as expected, I get a file and looks like there is data in it (for reference I have used pointers and malloc for the anInitialTestStruct but still don't get the desired result)

Now on the iphone, I copy the file into the project, and do this:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"dat"];
NSData *myVecNSData = [[NSData alloc] initWithContentsOfFile:filePath options:NSDataReadingUncached error:&error];
if ( error ) {
    NSLog(@"%@", error);
}

I don't get the correct data back. Interestingly if I run the initWithContents method on the mac and read the file in there it appears to be ok.

So I'm thinking there is something different on the iphone / mac way it deals with the filesystem.... I've tried encoding the data using NSKeyedArchiver, but I get an exception stating "incomprehensible archive....."

Nicolas Henneaux
  • 11,507
  • 11
  • 57
  • 82
Darren
  • 269
  • 3
  • 8
  • I guess that the main problem is that you are trying to use objects methods on a struct. Try to wrap the struct in an NSValue, later try covert in an NSdata and write to file. Of course remeber that when you restore the file you'll get an NSValue and you'll need to extract the struct. – Andrea Apr 05 '13 at 07:37
  • Thanks Andrea, I've tried to wrap it up in a NSValue and that seems fine (although file size is only 8 bytes when I write it). I'm having difficult getting the data back into NSValue, do we read the data into an NSData and then get it into NSValue? Not too sure how to do that, will read up and see how far I can get. – Darren Apr 05 '13 at 15:28

2 Answers2

1

For case of your "object" structure you have to store "xy" and "xyz" structures separately, for example in a dictionary:

    struct object anInitialTestStruct;
    NSDictionary *structureDataAsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                     [NSMutableData dataWithBytes:anInitialTestStruct.myXY length:sizeof(xy)], @"xy key",
                                     [NSMutableData dataWithBytes:anInitialTestStruct.myXYZ length:sizeof(xyz)], @"xyz key",
                                     nil];
    NSData *myTestDataOut = [NSKeyedArchiver archivedDataWithRootObject:structureDataAsDictionary];
    BOOL good = [myTestDataOut writeToFile:[NSString stringWithFormat:@"%@/filename.dat", docsDirectory] atomically:YES];

and decoding is something like this:

    struct object anInitialTestStruct;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"dat"];
    NSData *myVecNSData = [[NSData alloc] initWithContentsOfFile:filePath options:NSDataReadingUncached error:&error];
    if ( error ) {
        NSLog(@"%@", error);
    }
    // retrieving dictionary from NSData
    NSDictionary *structureDataAsDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:myVecNSData];
    // allocating memory for myXY and myXYZ fields
    anInitialTestStruct.myXY = (xy*)malloc(sizeof(xy));
    if (anInitialTestStruct.myXY == NULL) {
        // error handling
    }
    anInitialTestStruct.myXYZ = (xyz*)malloc(sizeof(xyz));
    if (anInitialTestStruct.myXYZ == NULL) {
        // error handling
    }
    // filling myXY and myXYZ fields with read data
    [[structureDataAsDictionary objectForKey:@"xy key"] getBytes:anInitialTestStruct.myXY];
    [[structureDataAsDictionary objectForKey:@"xyz key"] getBytes:anInitialTestStruct.myXYZ];
slavik
  • 1,341
  • 2
  • 11
  • 16
  • Thanks, I like this answer, keeps the structure of the data. I actually got my requirements to work. I'll post the code up shortly for comparison. – Darren Dec 03 '13 at 11:27
0

You might have truble encoding your pointers see here

"Pointers

You can’t encode a pointer and get back something useful at decode time. You have to encode the information to which the pointer is pointing. This is true in non-keyed coding as well. ..."

Dan Shelly
  • 5,991
  • 2
  • 22
  • 26
  • Hi, thanks Dan,Its not the encoding I've been having issues with, I was using the encoding in an attempt to get around my issue. Basically I want to get data from a mac to a file in my iphone project. The data saved on the Mac and re-opened on the Mac appears fine, but when the data file is copied to my iphone project the data is incorrect. I was using NSData for this, but I'm now hainvg problems get NSData and NSValue to share the same data re Andrea's comment above. – Darren Apr 06 '13 at 05:14