Save image in NSUserDefaults [closed] - ios

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I need to store and retrieve images in my app, I first thought of doing it like so:
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:key];
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:key];
UIImage* image = [UIImage imageWithData:imageData];
But I read this isn't the recommended way. What is the best approach for this?
(I know there are duplicates of this question, but I haven't understood how to do it yet)

The best way to store images depends on what your app does.
If you have 100k+ images you probably want to save it manually to the iphone's hard disk over coredata since it will load images faster this way.
However, if you have less than that, then storing images as binary data in core data is what I would recommend.
The benefits of using coredata vs the file system:
Better iCloud Sync Support
No need to manage images on the hard disk as well as what ever you use as a 'persistence store' (coredata/nsuserdefaults/custom)
You can tie images to other data such as name, created date, ect.
Some interesting performance info with filesystem vs coredata: http://biasedbit.com/filesystem-vs-coredata-image-cache/

You'd have to take the data from UIImageJPEGRepresentation() and store it in an NSData object or some such in order for it to be "plist-serializable" to store in NSUserDefaults, but as others have said, you're much better off storing the image as an image file on the file system somewhere and storing the file path or file URL in NSUserDefaults.

Save the image in the Documents directory, then save the file name in a database (Core Data perhaps), another file format or NSUserDefaults.
NSUserDefaults is not really a great way to store app data.
From a UIImage instance get the data with
UIImagePNGRepresentation() or UIImageJPEGRepresentation(). Then save the data to a file. Use imageWithContentsOfFile: to recover the UIImage.
To obtain the path to the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];

The easiest way for you is to directly save the content to your iOS Device and store the path in the NSUserDefaults.
First convert the image to a file and save it to the phone.
UIImage *image = // your image
NSData *pngImageData = UIImagePNGRepresentation(image);
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
NSString *fileName = [NSString stringWithFormat:#"%#/imageName.png",
documentsDirectory];
[pngImageData writeToFile:fileName atomically:YES];
Some are against storing filePaths in NSUserDefaults because, you're not suppose to store anything in NSUserDefaults that is super dynamic, you're suppose to store things like session keys, or token values, user names even, things that don't change often or are very strict.
The suggestion is, if you absolutely refuse CoreData, to make a property list and store the string name there.
To store your imagePath in a plist you would do the following:
NSString *textPath = [[NSBundle mainBundle] pathForResource:#"propertyListName" ofType:#"plist"];
NSDictionary *thisDict = [NSDictionary dictionaryWithContentsOfFile:textPath];
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:thisDict];
mutableDictionary[#"key"] = fileName;
[mutableDictionary writeToFile:resultsPath atomically:YES];
To retrieve your image from a plist you would do the following
NSString *textPath = [[NSBundle mainBundle] pathForResource:#"propertyListName" ofType:#"plist"];
NSDictionary *thisDict = [NSDictionary dictionaryWithContentsOfFile:textPath];
NSString *imagePath = thisDict[#"key"];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
UIImage *myImage = [UIImage imageWithData:imageData];
Do not use this NSUserDefaults option for it is wrong, but if you wanted to, this is how you would do it.
[[NSUserDefaults standardUserDefaults] setObject:fileName forKey:#"key"];
[[NSUserDefaults standardUserDefaults] synchronize];
now it's saved easily for you to retrieve. When you want to retrieve the image.
NSString *filePath = [[NSUserDefaults standardUserDefaults] objectForKey:#"key"];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
UIImage *myImage = [UIImage imageWithData:imageData];
then use myImage as the image. Remember the key must be the same when setting and retrieving.
The best way to store images depends on what your app does.
If you have 100k+ images you probably want to save it manually to the iphone's hard disk over coredata since it will load images faster this way.
However, if you have less than that, then storing images as binary data in core data is what I would recommend.
The benefits of using coredata vs the file system:
Better iCloud Sync Support
No need to manage images on the hard disk as well as what ever you use as a 'persistence store' (coredata/nsuserdefaults/custom)
You can tie images to other data such as name, created date, ect.
Some interesting performance info with filesystem vs coredata: http://biasedbit.com/filesystem-vs-coredata-image-cache/

Related

local memory as well as webservice

even after so many research i haven't found a solution for this question. I am currently working on a app which uses 3 view controllers for Registration with a log out button. the last view controller has the Register button which saves all the details of registration in a web service. But if the user has filled the two view forms and logs out. The two view filled forms field should be saved in the local memory and wen the user logs it again the pre filled forms should load the fields saved in internal memory just to continue the Registration for webservice. Any idea how to implement this sort of functionality
As others have said, NSUserDefaults will suffice for what you need.
NSUserDefaults *registrationInfo = [NSUserDefaults standardUserDefaults];
Guessing you have text fields with the info you need. So pull out the text and save to a key like this.
[registrationInfo setObject:self.someTextFieldName.text forKey#"firstTextField"];
After repeating this for every text field(use different key names though), call this [registrationInfo synchronize];
To pull the data out, you open the defaults again just like the first line. And to retrieve a specific key: NSString *firstTextField = [registrationInfo objectForKey:#"firstTextField"];
To make this easier, you can also put all of your strings in an array or dictionary, and then add that as an object in your defaults. Then you only have to set/get once.
If you have large amount of data to save use CoreData else you NSUserDefaults to save it.
I suggest you to use PLIST There are mainly three steps to do this.
1) Generate .plist file.
NSError *error1;
BOOL resourcesAlreadyInDocumentsDirectory;
BOOL copied1;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath1 = [documentsDirectory stringByAppendingString:#"/epub.plist"];
resourcesAlreadyInDocumentsDirectory = [fileManager fileExistsAtPath:filePath1];
if(resourcesAlreadyInDocumentsDirectory == YES) {
} else {
NSString *path1 = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:#"/epub.plist"];
copied1 = [fileManager copyItemAtPath:path1 toPath:filePath1 error:&error1];
if (!copied1) {
NSAssert1(0, #"Failed to copy epub.plist. Error %#", [error1 localizedDescription]);
}
}
2) Try to read(open) it.
NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
3) write data to plist file.
[dict setObject:[NSNumber numberWithInt:value] forKey:#"value"];
[dict writeToFile:path atomically:YES];
This is a simple way to use it. I suggest to use .plist file in place of NSUserDefaults.

Optimum way to make an auto back up of photos on server?

What I've known:
How make requests to server for uploading I will use AFNetworking
How access photos and videos with help of ALAssetsLibrary
I think I must use CoreData to keep info about:last syncing, photos already uploaded, etc. I worked already with coreData it will no be a problem.
My problems are logic, flow how can achieve this auto back up and of course to be optimum(minimum requests, short way). What steps must follow to achieve this scope?
Any thoughts?
I think CoreData is too heavy in this situation. You may want to use plist to store your info data .here are some steps to follow .
After loading image from server, create a dictionary to store the message you want and create another dictionary to store these messages , and use image's url as the key of this dictionary. It might look like this:
imageUrl = {
lastSyncTime = xxxxxxxxxx,
photoUploaded = 0,
}
Create a plist file to save this dictionary:
- (NSString *)filePath:(NSString *) fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:fileName];
}
[yourImageDictionary writeToFile:[self filePath:#"imageInfo.plist"] atomically:YES];
Read or write your plist file anytime you want:
if ([[NSFileManager defaultManager] fileExistsAtPath:[self filePath:#"imageInfo.plist"]]) {
NSDictionary *imageInfo = [NSDictionary dictionaryWithContentsOfFile:[self filePath:#"imageInfo.plist"]];
}

Saving an Mutable array of images and loading them

I have part of my app that will take a photo and the person can elect to save it i then save the image to an array but what ways can I save it to the phone WITHOUT it being put in the photo library. I tried
UIImage *image = imageView1.image;
[array addObject: image];
NSUserDefaults *default = [NSUserDefault standardDefaults];
[defaults setObject:image withKey:#"saved image"]; //not exact code just showing the method
I use to save the array of images
[defaults synchronize];
then i also use UserDefaults to load array but it does not work. I am wondering if there is a different way to save images without saving them to the photo library.
In principle, you could save the images in NSUserDefaults using
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image)
forKey:key];
But keep in mind that NSUserDefaults is meant for storage of preferences, not images. You better save the images in the documents folder and store the path in NSUserDefaults (as suggested by Wain).
You cannot save images the way you want. In your case, array contains just pointers to the images, not images itself. So, one way around is, as #Wain suggested, writing image to the disk, and add path of the saved image to the array, and then saving that array to the NSUserDefaults. You can save image to the disk by converting it to the NSData, and writing it in Documents or tmp folders of application sandbox. In order to convert image to the NSData, you could use UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality) method, and in order to write data to the disk, use writeToFile:atomically method of NSData.
Good Luck!
You can save them into the Document directory:
NSData *imageData = UIImagePNGRepresentation(imageView1.image);
NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"/imageName.png"];
[imageData writeToFile:imagePath atomically:YES];
And save their URLs in NSUserDefaults:
NSUserDefaults *default = [NSUserDefault standardDefaults];
[defaults setObject:imagePath withKey:#"saved image "];
[defaults synchronize];
And simply retrieve image:
UIImage *customImage = [UIImage imageWithContentsOfFile:imagePath];

Memory warning when saving to NSData Array

I'm building an application that allows the user to take several pictures in a row with the device camera.
Every time a picture is taken, it is sent to an array as an NSData variable. The problem is: when the array gets like 30 pictures, it starts to create memory warnings and eventually crashes the application.
When I leave that view I save that array to NSUserDefaults, which can also lead to memory warnings and crashing.
I need to be able to save information of like 200 taken pictures. How can I achieve this without memory warnings?
Btw: I'm using the Apple's SquareCam sample code to take pictures with the camera.
Thanks in advance.
If you don't scale/save as jpg, a photo could be quite big. A solution would be to save it on "disk" in sandbox immediately (with jpeg format would be a good idea anyway) and store in your array only the path of the file you saved.
See a sample code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* imgName = [NSString stringWithFormat:#"%#.jpg", self.uid];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:imgName];
NSData *webData = UIImageJPEGRepresentation(self.theImage, 0.5);
[webData writeToFile:imagePath atomically:YES];
self.imageURL = imagePath;
Please don't save image just save only path of image.so, u can better manage them and better for your app. performance.

Best way to store the downloaded images in iOS

Which is the best way to store the downloaded images? From there I should be able to use them anywhere in my application, and images should not be deleted at any case (like low space). Any help please.
As per the standard, App related files(Data) need to be stored in document directory only. Once image get download store that images in document directory and maintain unique name for image identification.
-(NSString *)writeDataAsFile:(NSData *)imageData
{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * thumbNailFilename = [NSString stringWithFormat:#"%#.png",[self GetUUID]]; // Create unique iD
NSString * thumbNailAppFile = [documentsDirectory stringByAppendingPathComponent:thumbNailFilename];
if ([imageData writeToFile:thumbNailAppFile atomically:YES])
{
return thumbNailFilename;
}
return nil;
}
use this method to store the image(downloaded NSData) in document directory.
Retrieve image from the document directory like this
UIImage *thumbnailHomeImage = [UIImage imageWithContentsOfFile:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"%#",imageName]];
take a look at this image caching library. ive used it quite a few times, its really useful

Resources