hopola
hopola

Reputation: 11

Write a NSMutableArray in a text file

i'm trying to write a table in a txt file, but my code seems doesn't working.

    Action *action1 = [[Action alloc] init];
    Action *action2 = [[Action alloc] init];
    ActionEtrangere *action3 = [[ActionEtrangere alloc] init];

    [action1 setPrixAchatAction:2.30];
    [action1 setPrixActuelAction:4.50];
    [action1 setNbActions:40];

    [action2 setPrixAchatAction:12.19];
    [action2 setPrixActuelAction:10.59];
    [action2 setNbActions:90];

    [action3 setPrixAchatAction:45.10];
    [action3 setPrixActuelAction:49.51];
    [action3 setNbActions:210];
    [action3 setTauxConversion:0.94];

    NSMutableArray *porteMonnaie = [[NSMutableArray alloc] initWithObjects:action1, action2, action3, nil];

    for (Action *p in porteMonnaie) {
        NSLog(@"Le cout en euros est de %.2f et la valeur en euro de %.2f", [p coutEnEuros], [p valeurEnEuros]);
    }

    //save des valeurs
    BOOL save = [porteMonnaie writeToFile:@"/tmp/save.txt" atomically:YES];

    if (!save) {
        NSLog(@"Error Save");
    } else {
        NSLog(@"Save ok");
    }

}
return 0;

}

if you have some idea ! maybe i can't write a mutable in a txt ?

thanks

Upvotes: 0

Views: 136

Answers (3)

Hussain Shabbir
Hussain Shabbir

Reputation: 14995

The main reason why your array is not writing to file:-

As per the documentation, writeToFile:automatically: only works if your array's contents are following of types (NSString, NSData, NSArray, or NSDictionary objects). If you have any other type of object in your array, then it will not write to file correctly. And that bool flag will always return NO

Upvotes: 0

vikingosegundo
vikingosegundo

Reputation: 52227

writeToFile:automatically: isn't able to write custom objects to disk.

You can do so by implementing the NSCoding protocol and use NSKeyedArchiver to write to and NSKeyedUnarchiver to read from disk.

the protocol has two methods you must implement.

-(id)initWithCoder:(NSCoder *)decoder and -(void)encodeWithCoder:(NSCoder *)encoder.

For Action it might be

@implementation Action

-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if (!self) {
        return nil;
    }

    self.prixAchatAction = [[decoder decodeObjectForKey:@"prixAchatAction"] doubleValue];
    self.prixActuelAction = [[decoder decodeObjectForKey:@"prixActuelAction"] doubleValue];
    self.nbActions = [decoder decodeIntegerForKey:@"nbActions"];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:@(self.prixAchatAction) forKey:@"prixAchatAction"];
    [encoder encodeObject:@(self.prixActuelAction) forKey:@"prixActuelAction"];
    [encoder encodeInteger:self.nbActions forKey:@"nbActions"];

}

@end

And for ActionEtrangere

@interface ActionEtrangere : Action
@property (nonatomic, assign) CGFloat tauxConversion;
@end

@implementation ActionEtrangere
-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super initWithCoder:decoder];
    if (!self) {
        return nil;
    }
    self.tauxConversion = [[decoder decodeObjectForKey:@"tauxConversion"] doubleValue];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [super encodeWithCoder:encoder];
    [encoder encodeObject:@(self.tauxConversion) forKey:@"tauxConversion"];
}

Now you can write your portemonnaie like:

BOOL success = [NSKeyedArchiver archiveRootObject:porteMonnaie
                                           toFile:[NSHomeDirectory() stringByAppendingPathComponent:@"portemonnaie"]];
if(!success) {
    NSLog(@"something went wrong");
}

And read it like:

NSArray *newporteMonnaie = [NSKeyedUnarchiver unarchiveObjectWithFile:[NSHomeDirectory() stringByAppendingPathComponent:@"portemonnaie"]];

A full command line program:


#import <Foundation/Foundation.h>


@interface Action : NSObject <NSCoding>
@property (nonatomic, assign) CGFloat prixAchatAction;
@property (nonatomic, assign) CGFloat prixActuelAction;
@property (nonatomic, assign) NSInteger nbActions;

@end

@implementation Action

-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if (!self) {
        return nil;
    }

    self.prixAchatAction = [[decoder decodeObjectForKey:@"prixAchatAction"] doubleValue];
    self.prixActuelAction = [[decoder decodeObjectForKey:@"prixActuelAction"] doubleValue];
    self.nbActions = [decoder decodeIntegerForKey:@"nbActions"];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:@(self.prixAchatAction) forKey:@"prixAchatAction"];
    [encoder encodeObject:@(self.prixActuelAction) forKey:@"prixActuelAction"];
    [encoder encodeInteger:self.nbActions forKey:@"nbActions"];

}

@end


@interface ActionEtrangere : Action
@property (nonatomic, assign) CGFloat tauxConversion;
@end

@implementation ActionEtrangere
-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super initWithCoder:decoder];
    if (!self) {
        return nil;
    }
    self.tauxConversion = [[decoder decodeObjectForKey:@"tauxConversion"] doubleValue];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [super encodeWithCoder:encoder];
    [encoder encodeObject:@(self.tauxConversion) forKey:@"tauxConversion"];
}


@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        Action *action1 = [[Action alloc] init];
        Action *action2 = [[Action alloc] init];
        ActionEtrangere *action3 = [[ActionEtrangere alloc] init];

        [action1 setPrixAchatAction:2.30];
        [action1 setPrixActuelAction:4.50];
        [action1 setNbActions:40];

        [action2 setPrixAchatAction:12.19];
        [action2 setPrixActuelAction:10.59];
        [action2 setNbActions:90];

        [action3 setPrixAchatAction:45.10];
        [action3 setPrixActuelAction:49.51];
        [action3 setNbActions:210];
        [action3 setTauxConversion:0.94];

        NSArray *porteMonnaie = @[action1, action2,action3];

        BOOL success = [NSKeyedArchiver archiveRootObject:porteMonnaie
                                                   toFile:[NSHomeDirectory() stringByAppendingPathComponent:@"portemonnaie2.plist"]];
        if(!success) {
            NSLog(@"something went wrong");
        } else {
            NSArray *newporteMonnaie = [NSKeyedUnarchiver unarchiveObjectWithFile:[NSHomeDirectory() stringByAppendingPathComponent:@"portemonnaie2.plist"]];

        }
    }
    return 0;
}

Upvotes: 0

holex
holex

Reputation: 24041

you may want to save your file into your application's sandbox instead, I guess:

NSString *_filename = @"save.txt"
NSURL *_resourceURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:_fileName];

I also assume that all items in the array conforms the NSCoding protocol, so that should work now:

NSMutableArray *porteMonnaie = [[NSMutableArray alloc] initWithObjects:action1, action2, action3, nil];
BOOL _isSaved = [porteMonnaie writeToFile:[_resourceURL path] atomically:TRUE];

Upvotes: 1

Related Questions