my inquiry is this: I am saving and loading custom objects to file. Loading and creating files with the data works correctly, however, after a file has loaded, saving again crashes. Long story short, saving a file that has been loaded causes a crash upon saving.
The crash sends me to my custom objects m file:
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeInteger:*(time) forKey:#"time"];
[encoder encodeInteger:*(location) forKey:#"location"];
}
//====
Loading the data from file:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
initWithContentsOfFile:filePath];
globals.mainData = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
//====
Saving to current file
My breakpoint stop me at: NSData *data = ... //and then crashes
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:currentFileName];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:globals.mainData]; //crashes here
BOOL saved = [data writeToFile:filePath options:NSDataWritingAtomic error:nil];
if (saved) {
NSLog(#"Saved %#", currentFileName);
}else{
NSLog(#"Error - code 2 - Failure to save data");
}
Any advice would be awesome and much appreciated!
Related
I'm trying to get a file which contains, on separate lines, all the time zone names contained in the knownTimeZoneNames variable of the NSTimeZone class. I'm quite new to Objective-C, though; here is what I've tried so far:
#import <Foundation/Foundation.h>
#import <stdio.h>
int main(void)
{
FILE *fp;
fp = fopen("knownTimeZoneNames.txt", "w+");
for (NSTimeZone* timezone in [NSTimeZone knownTimeZoneNames]) {
fputs(timezone, fp);
}
fclose(fp);
return 0;
}
The problem is that the file I get does not seem to be human-readable. What would be the correct way to do this?
Take your string write to file.
//Method writes a string to a text file
-(void) writeToTextFile{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/textfile.txt",
documentsDirectory];
//create content - four lines of text
NSString *content = #"One\nTwo\nThree\nFour\nFive";
//save content to the documents directory
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil];
}
//Method retrieves content from documents directory and
//displays it in an alert
-(void) displayContent{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/textfile.txt",
documentsDirectory];
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
usedEncoding:nil
error:nil];
//use simple alert from my library (see previous post for details)
[ASFunctions alert:content];
[content release];
}
It would seem that my apps no longer are able to save files to their documents folder when doing this:
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *dta = [[NSData alloc] init];
dta = [NSData dataWithContentsOfFile:path];
NSLog(#"writing file: %#", path);
if ([dta writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}else {
NSLog(#"Written: %#", path);
[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:path]];
}
I do get "Written" in the log with the full path:
Written: /var/mobile/Containers/Data/Application/ECBCD65D-A990-4758-A07F-ECE48E269278/Documents/9d440408-4758-4219-9c9c-12fe69cf82f2_pdf.pdf
And as long as I don't quit the app I can load the PDF in a UIWebView like this (pdfPath is a string that I pass to the function that loads the PDF file):
[www loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:pdfPath]]];
Any help at all is as always greatly appreciated.
Okay, after mucking about I found that since the documents directory changes path every time I run the app, I had to:
Write the file to the documents folder with the complete path to
the file:
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent: fileName];
NSData *dta = [[NSData alloc] init];
dta = [NSData dataWithContentsOfFile:path];
if ([dta writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}else {
NSLog(#"Written: %#", path);
[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:path]];
}
Save only the file name to my database
Load the file by using the full newly generated Documents directory path and append the file name from my database:
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent: pdfPath];
Using the code below is the only way I can get writeToFile to actually save a file. It outputs to this directory:
/Users/Eric/Library/Containers/net.ericmann.Event-Gadget-Workshop-App/Data/Documents/gadget.ics
- (IBAction)Saved:(id)sender {
[self writeToTextFile];
//mySaved.stringValue = [NSString stringWithFormat:#"Saved!"];
}
-(void) writeToTextFile{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//NSString *pathToDesktop = [NSString stringWithFormat:#"/Users/%#/Desktop", NSUserName()];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/gadget.ics", documentsDirectory];
//create content - four lines of text
NSString *content = myOutput.stringValue;
//save content to the documents directory
[content writeToFile:fileName atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
mySaved.stringValue = fileName;
myTestBox.stringValue = fileName;
}
Now, if I use the code below, nothing will write. I have the test file name output, and it's pointing here:
/Users/Eric/Desktop/gadget.ics
-(void) writeToTextFile{
//get the documents directory:
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
//NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathToDesktop = [NSString stringWithFormat:#"/Users/%#/Desktop", NSUserName()];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/gadget.ics", pathToDesktop];
//create content - four lines of text
NSString *content = myOutput.stringValue;
//save content to the documents directory
[content writeToFile:fileName atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
mySaved.stringValue = fileName;
myTestBox.stringValue = fileName;
You will likely end up figuring out a solution if you actually make use of the error parameter there in the "writeToFile" method:
e.g.:
NSError * error = NULL;
BOOL success = [content writeToFile:fileName atomically:NO encoding:NSUTF8StringEncoding error:&error];
if(success == NO)
{
NSLog( #"error saving to %# - %#", fileName, [error localizedDescription] );
}
I'm really struggling with this,Day three of the unending quest to save and load an image in my app. I'm picking an image from camera roll and trying to save it to the device via the appsdocsdirectory.
in the Appdelegate.m I have:
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
}
in the class I want to save and load the image (picked from camera roll into UI imageView)
- (IBAction)save:(id)sender {
UIImage *myImage = [imageView image];
NSData *data = UIImagePNGRepresentation(myImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *appDocsDirectory = [paths objectAtIndex:0];
}
- (IBAction)load:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *appDocsDirectory = [paths objectAtIndex:0];
UIImage* thumImage = [UIImage imageWithContentsOfFile: [NSString stringWithFormat:#"%#/%#.png", appDocsDirectory, #"myNewFile"]];
}
#end
I also imported Appdelegate.h, in this class, not sure if that was needed or correct?Now I have finally got rid of all errors and no exceptions being thrown but now my problem is nothing happens when I try to save the image and load it. I'm also getting yellow triangles telling me i have unused veriables in load UIImage* thumImage NSString *appDocsDirectory & NSData *data so I may have made a royal hash of this.
This is how I did it in one of my project.
I get the picture with the delegate method ot the imagePickerController :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
pictureInfo = info;
}
Then I save it like this :
-(void)createPin
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pinFolderName = [NSString stringWithFormat:#"%f",[[NSDate date] timeIntervalSince1970]];
NSString *pinFolderPath = [documentsDirectory stringByAppendingPathComponent:pinFolderName];
[fileManager createDirectoryAtPath:pinFolderPath withIntermediateDirectories:YES attributes:nil error:NULL];
self.fullsizePath = [pinFolderPath stringByAppendingPathComponent:#"fullsize.png"];
NSString *mediaType = [pictureInfo objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *fullsizeImage = [pictureInfo objectForKey:UIImagePickerControllerEditedImage];
NSData *fullsizeData = UIImagePNGRepresentation(fullsizeImage);
[fullsizeData writeToFile:self.fullsizePath atomically:YES];
}
}
Hope you can start from there.
If you need any explanations or help, feel free to ask
I have used NSuser defaults, all sorted
Can someone explain and give example code to do the following steps in my iPad app:
do some things in my app, which generates some data (as a string)
write that data to a text file
be able to plug in my iPad to my computer and grab those text files off
How can I do this?
For writing string in a file use this
NSString *str = #"your string";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:#"data.txt"];
NSError *error;
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
Then set Application supports iTunes file sharing key to YES in your plist file.
When you connect your device with iTunes from there you can save your data.txt
Here is the video how to get files from iTunes
Edited as requested.
NSUserDefaults *deflt = [NSUserDefaults standardUserDefaults];
//this number file is saved, I'm not saving the file name as data0.txt.
//The first file to be saved is data1.txt
int num = [deflt integerForKey:#"fileNameNum"];
num++;
NSString *fileName = [NSString stringWithFormat:#"data%d.txt",num];;
NSString *str = #"your string";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSError *error = nil;
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error == nil) {
//Save the number of the file that you have save in doc directory
[deflt setInteger:num forKey:#"fileNameNum"];
}