0

I had a look around, trying to find a straightforward method for first saving a MutableArray (which will contain different text arrays from UITextViews with returns etc.) into a txt-file and then loading the txt-file back into my MutableArray.

I didn't manage to come up with the reverse method (loading the text-file) and was wondering how I should go about this. I'm sure txt files and mutable arrays are not really compatible, especially if I want the MutableArray to hold various text strings from UITextViews.

Is there a way to mark the beginning of one section in a mutable array and the beginning of the next in a txt file? The aim would be to be able to edit the txt file both in the program and in a simple text editor without messing up the structure of the mutable array.

Can I use a certain special character (not \n obviously) in my text file so as to separate different objects?

Here is what I've come up with so far. Sorry, I'm a beginner and it's very basic. The first problem is that I get the error message 'NSMutableArray' may not respond to '-writeToFile:atomically:encoding:error:'. Next, I have no idea how to load the txt back into my Array. Finally, I'd like to come up with a way to separate the arrays in the txt so that it remains editable, but that would be the absolute icing. Perhaps a solution would be to save each Object in an Array in a separate txt file and then load each txt into the array?

// GENERATE ARRAY

NoteBook = [[NSMutableArray alloc] init];

for (int temp = 0; temp < 3; temp++) {
    [NoteBook insertObject:@"Title\n\n Line1\nLine2..." atIndex:temp];
}

// SAVING MY MUTABLE ARRAY

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory

NSError *error;
BOOL succeed = [NoteBook writeToFile:[documentsDirectory stringByAppendingPathComponent:@"myfile.txt"]
                          atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!succeed){
    // Handle error here
}



// LOADING TEXTFILE AND PUT IT INTO A MUTABLE ARRAY
// NO IDEA... how to do this

5 Answers 5

3

Convert your arrays into strings, and vice versa, using, e.g.,

NSString* arrayText = [NoteBook componentsJoinedByString: @"<your-favourite-separator-string>"];

the write to file using [arrayText writeToFile...]

After reading a string back from a file, use

Notebook = [arrayText componentsSeparatedByString: @"<your-favourite-separator-string>"];

Lastly, don't do this. Save your array directly to a property list (read up on those) or JSON or some other structured data format.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for this. I haven't tried it, but it makes perfect sense theoretically. Why do you suggest that I should not do this, though? If my aim is to make editing the txt as easy as possible, why shouldn't I go for this and choose JSON instead? Also, you can't edit a plist very easily (if at all) with a text editor.
No, you're right. If readability comes into play, plain text wins out of course.
Hi, I just tried this and the first step works perfectly. However, when trying to read the information back into my program, there seems to be a conflict when trying to convert an array to the MutableArray NoteBook: NoteBook = [tempTextOut componentsSeparatedByString: @"\n--- end of page ---\n"]; xCode tells me: Incompatible Objective-C types assigning 'struct NSArray*', expected 'struct NSMutableArray*'`. I guess this error message is quite clear, but I'm afraid I don't understand the problem here. I'd be very grateful if you could interpret the error message. Thanks!!
Just solved this with the help of others: stackoverflow.com/questions/5405328/…
2

Why not just turn the mutable array into JSON and write that string to a file? The inverse is to read the string from file and turn back into an array using the JSON parser. json-framework is very easy to use.

A benefit would be that you could create or modify your array by editing text files as long as you write valid JSON.

2 Comments

Thanks for this suggestion, I'll have a closer look at JSON. But I guess I'd rather like to stick to a pure txt file without any formatting. I guess the only solution is to have a separate file for each object in the array.
You'll like JSON once you try it. It is very readable, less punctuation than XML for example. This is a good JSON validator for checking any that you write yourself or formatting it nicely: jsonlint.com
2
  1. make NSMutableArray to NSArray .because NSMutableArray does not have writeToFile .
  2. retriev array from file

    NSArray *theCatalogInfo=nil;
    NSString *theCatalogFilePath = [NSString stringWithFormat:@"%@/Documents/",NSHomeDirectory()];
    theCatalogFilePath = [theCatalogFilePath stringByAppendingString:kCatalogCachePath];
    if(nil!=theCatalogFilePath)
    {
        theCatalogInfo=[[NSArray alloc]initWithContentsOfFile:theCatalogFilePath];
    }
    
  3. Save array To file

    NSString *theCatalogFilePath = [NSString stringWithFormat:@"%@/Documents/",NSHomeDirectory()];
    theCatalogFilePath = [theCatalogFilePath stringByAppendingString:kCatalogCachePath];
    
    [**YourArray** writeToFile:theCatalogFilePath atomically:YES];
    

1 Comment

NSMutableArray is a subclass of NSArray, and because of this NSMutableArray responds to writeToFile:atomically:. No need to create a NSArray.
0

Have a look at following three methods to create a text file, write to it and read the data from it. The key is to store the different objects separated by space. And you should get it very simple.

-(void)createFile
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"Sample.txt"]; 

    NSFileManager * file_manager = [NSFileManager defaultManager];

    if(![file_manager fileExistsAtPath:filePath])
    {
        [file_manager createFileAtPath:filePath contents:nil attributes:nil];

        NSString *content = @"NULL NULL NULL";
        [content writeToFile:filePath 
                  atomically:NO 
                    encoding:NSStringEncodingConversionAllowLossy 
                       error:nil];
    }

}

-(void)writeToFile
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"Sample.txt"]; 

    NSString *content = [NSString stringWithFormat:@"%@ %@ %@", obj1, obj2, obj3];

    [content writeToFile:filePath 
                atomically:NO 
                encoding:NSStringEncodingConversionAllowLossy 
                error:nil];
}

-(void)readFromFile
{
    objects = [[NSArray alloc] init];
    NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"Sample.txt"]; 
    if (filePath) {  
        NSString *myText = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:nil];  
        if (myText) { 
            objects = [myText componentsSeparatedByString:@" "];
        }
    }

}

2 Comments

NSStringEncodingConversionAllowLossy is not a valid encoding. createFile is a useless method if you overwrite the file in writeToFile. createFileAtPath:contents:attributes: is superfluous if you create another file in the next line. And you leak the old object in the first and last line of readFromFile. And nobody uses ascii these days.
@fluchtpunkt: ooops... it looked, in my very inexperienced eyes, as a rather structured reply.
0

if your nsarray contains nsdictionary, nsarray, nsstring, nsnumber, nsdata or nsdate objects (no custom objects, int's, etc) you can simply write the contents of your mutable array to a plist file.

this will maintain the data structure you have and you can simply read that data right into an array. How I do it in a couple of my data classes is

NSArray *tempArray = [NSArray arrayWithContentsOfFile:[Utils getFileLocation]];
if (tempArray == nil) {
    yourArray = [[NSMutableArray alloc] init];
} else {
    yourArray = [[NSArray deepMutableCopy:tempArray] retain];
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.