Objective-C save NSColor in NSUserDefaults - objective-c

How do you save the color of the dot so that when the app is opened and closed the dot is the color it was last set to by the user?
Could someone explain to me how to use NSUserDefaults and in which methods to declare NSUserDefaults.
So far i have this:
NSData *data = [NSArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"MyColor"];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyColor"];
NSColor *color = [NSUnarchiver unarchiveObjectWithData:data];
Link for tutorial I followed:
http://www.mactech.com/articles/mactech/Vol.25/25.04/2504RoadtoCode/index.html

This is what I use:
- (NSColor *)colorForKey:(NSString *)key
{
NSData *data;
NSColor *color;
data = [[NSUserDefaults standardUserDefaults] objectForKey:key];
color= [NSUnarchiver unarchiveObjectWithData:data];
if( ! [color isKindOfClass:[NSColor class]] )
{
color = nil;
}
return color;
}
- (void)setColor:(NSColor *)color forKey:(NSString *)key
{
NSData *data = [NSArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
[BFChatWindow refresh];
}

Related

Accessing imageurl using userdefaults in objective c

I have fetched the image from image picker and uploaded the image to web service and i have a image url.I have saved the imageurl using user defaults as given below:
-(void)postSignupService {
[NewJsonHelperClass postExecuteWithParams:#"signup" secondParm:[self signUpParams] onCompletion:^(NSDictionary *json){
if ([[json valueForKey:#"status"] isEqualToString:#"success"]) {
NSDictionary *dataDict =[NSDictionary new];
dataDict =[json valueForKey:#"user"];
[[NSUserDefaults standardUserDefaults] setObject:#"sucess" forKey:#"LoginStatus"];
[[NSUserDefaults standardUserDefaults] setObject:[dataDict valueForKey:#"_id"] forKey:#"user_Id"];
[[NSUserDefaults standardUserDefaults] setObject:[dataDict valueForKey:#"userName"] forKey:#"userName"];
[[NSUserDefaults standardUserDefaults] setObject:[dataDict valueForKey:#"password"] forKey:#"Password"];
[[NSUserDefaults standardUserDefaults] setObject:[dataDict valueForKey:#"email"] forKey:#"email_Id"];
[[NSUserDefaults standardUserDefaults] setObject:[dataDict valueForKey:#"profile_pic"] forKey:#"image_Str"];
NSLog(#"datadict is %#",dataDict);
SelectFoodVC *selectVc = [appDelegateRef.storyBoard instantiateViewControllerWithIdentifier:#"SelectFoodVC"];
[self.navigationController pushViewController:selectVc animated:YES];
// TabBarController *tabVc = [appDelegateRef.storyBoard instantiateViewControllerWithIdentifier:#"TabBarController"];
// [self.navigationController pushViewController:tabVc animated:YES];
}
else{
[reUse showAlertWithTitle:[json valueForKey:#"status"] message:[json valueForKey:#"user"] thirdParam:self];
}
}];
}
-(NSDictionary *)signUpParams {
NSMutableDictionary *params =[NSMutableDictionary new];
params[#"userName"] =self.userNameTf.text;
params[#"email"] =self.emailTf.text;
params[#"password"] =self.passwordTf.text;
NSLog(#"imgstr is %#",imgStr);
params[#"profile_pic"] =imgStr;
return params;
}
Here profile pic value is imgStr which is got as imageurl from web service.
When i try to retrieve the imageurl in different viewcontroller,the value of userdefault is null as it shows error.
NSString *urlstring = [[NSUserDefaults standardUserDefaults] objectForKey:#"image_Str"];
NSLog(#"urlstring is %#",urlstring);
Here urlstring is null and the error is Error: Request failed: not found (404)
NSString *str = [NSString stringWithFormat:#"http://swiftdeveloperblog.com/wp-content/uploads/2015/07/1.jpeg"];
NSURL *url = [NSURL URLWithString:str];
[[NSUserDefaults standardUserDefaults]setURL:url forKey:#"URL"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSString *getURL = [[NSUserDefaults standardUserDefaults]URLForKey:#"URL"];
NSLog(#"url is %#",getURL);

NSMutableArray isn't adding my NSString

Im trying to add a NSString to an NSMutableArray and then make the array into NSData and save it with NSUserDefaults. But the array is always nil.
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
library = [[ALAssetsLibrary alloc] init];
groups = [[NSMutableArray alloc] init];
userDefaults = [[NSUserDefaults alloc] init];
NSData *data = [userDefaults objectForKey:#"GroupArray"];
groups = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(#"%i", [groups count]);
}
-(IBAction)newFolder {
if (textField.text != nil) {
NSString *string = textField.text.capitalizedString;
[library addAssetsGroupAlbumWithName:string
resultBlock:^(ALAssetsGroup *group) {
NSLog(#"Created a folder named: %#", group);
}
failureBlock:^(NSError *error) {
NSLog(#"An error occured! - %#", error);
}
];
[groups addObject:string];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:groups];
[userDefaults setObject:data forKey:#"GroupArray"];
NSLog(#"%i", [groups count]);
}
[self.view sendSubviewToBack:subView];
}
When the app starts i get a message in the console that the array is NULL. When I try to add the string the NSLog(#"%i", [groups count]); always return 0.
Why does this happen?
userDefaults = [[NSUserDefaults alloc] init];
NSData *data = [userDefaults objectForKey:#"GroupArray"];
In this case, data will be nil when the code is executed for the first time, since there is yet no "GroupArray" property present.
groups = [NSKeyedUnarchiver unarchiveObjectWithData:data];
This causes groups be become nil as well, because calling unarchiveObjectWithData: with nil as an argument will return nil as well.
And because of all that, in -newFolder, [groups addObject:string] becomes [nil addObject:string]
Calling a method on nil is allowed in Objective-C, so you get no exception there. The return value of any method called on nil is, again, nil or 0.
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:groups];
This causes data to be nil because groups is nil.
So you are always calling:
[userDefaults setObject:data forKey:#"GroupArray"];
with data = nil
Quick fix:
Add if (groups == nil) groups = [NSMutableArray array]; to the beginning of -newFolder
In view didLoad method every time you are initialising new instance of NSUserDefaults and calling
NSData *data = [userDefaults objectForKey:#"GroupArray"]; on the newly created object
which will return nil all the time because in the new instance there wont be any object for key #"GroupArray". Instead replace userDefaults with singleton object [NSUserDefaults standardUserDefaults]
Modify your code as shown below
- (void)viewDidLoad
{
[super viewDidLoad];
library = [[ALAssetsLibrary alloc] init];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"GroupArray"];
groups = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if (!groups)
{
groups = [[NSMutableArray alloc] init];
}
NSLog(#"group %#", groups);
NSLog(#"%i", [groups count]);
}
Your newFolder method
-(IBAction)newFolder
{
if (textField.text != nil)
{
NSString *string = textField.text.capitalizedString;
[library addAssetsGroupAlbumWithName:string
resultBlock:^(ALAssetsGroup *group) {
NSLog(#"Created a folder named: %#", group);
}
failureBlock:^(NSError *error) {
NSLog(#"An error occured! - %#", error);
}
];
[groups addObject:string];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:groups];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"GroupArray"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%i", [groups count]);
}
[self.view sendSubviewToBack:subView];
}
This should work. As it worked for me.

Encode NSMutableArray

EDIT: Ok i decided to save the array in the userDefaults... should be easy, right ?
Save:
NSUserDefaults *userDefs = [NSUserDefaults standardUserDefaults];
[userDefs setObject:videoArray forKey:#"dataArray"];
[userDefs synchronize];
Load:
NSUserDefaults *userDefs = [NSUserDefaults standardUserDefaults];
videoArray = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"dataArray"];
[tableview reloadData];
NSLog(#"%#",videoArray);
Class of the objects which are in the array:
#interface DEVideoModel : NSObject
#property (copy) NSString *name;
#property (copy) NSImage *thumbnail;
#property (copy) NSDictionary *qualities;
#property (readwrite) float videoSize;
#property (readwrite) float progress;
#property (copy) NSString *filePath;
#property (copy) NSDate *datum;
#end
#synthesize name,filePath,videoSize,qualities,thumbnail,datum,progress;
-(id)init {
self = [super init];
if(self) {
qualities = [[NSDictionary alloc]init];
thumbnail = [[NSImage alloc]init];
}
return self;
}
#end
And my videoArray is (null) when i load it ?! I don't get it. videoArray is a NSMutableArray not NSArray by the way.
IN your code you are writting NSData to NSCoder, so you need to read NSData then convert it to Array.
NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
NSString *path = [NSString stringWithFormat:#"%#/DEConvert.dat",[appSupportDir path]];
NSLog(#"%#",appSupportDir);
NSData *data = [NSData dataWithContentsOfFile:path];
NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
to store object in NSUserDefault
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"your key"];
Unarchiving is just as easy:
NSData *NewData = [[NSUserDefaults standardUserDefaults] objectForKey:#"your key"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:NewData];

Save and load text color

I looked and looked and looked for this and when i finally find something it does not work. I am trying to save and load text color that the user selects. Here is my save button:
-(IBAction)save123456 {
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:textview];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:#"myColor"];
}
And here is my load:
-(IBAction)load123456 {
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:#"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
}
My text view is textview if that helps. Also i am linking everything via tuchupinside so let me know if i should change anything.
Also if anyone knows how to save text font that the user selects would also be helpful. Thanks so much!!
Well , you could save the RGB of the color. And the font-name of the font.
So when you're saving , store these values for font: font.fontName , font.pointSize
and RGB of the color. Here you can see how to get the RGB of a UIColor object.
These are all NSString and float values so you shouldn't have any problem in saving them.
- (NSString *) pahtForFile:(NSString*) filename
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:filename];
}
- (void) save
{
//get RGB and fontName , fontSize like I explained above
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:fontName forKey:#"fontName"];
[dictionary setObject:[NSNumber numberWithFloat:fontSize] forKey:#"fontSize"];
[dictionary setObject:[NSNumber numberWithFloat:red] forKey:#"red"];
[dictionary setObject:[NSNumber numberWithFloat:green] forKey:#"green"];
[dictionary setObject:[NSNumber numberWithFloat:blue] forKey:#"blue"];
NSString *filepath = [self pathForFile:#"save.plist"];
[dictionary writeToFile:filepath atomically:TRUE];
}
- (void) load
{
float red,green,blue,fontSize;
NSString *fontName;
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[self pahtForFile:#"save.plist"]];
red = [[dictionary objectForKey:#"red"] floatValue];
green = [[dictionary objectForKey:#"green"] floatValue];
blue = [[dictionary objectForKey:#"blue"] floatValue];
fontSize = [[dictionary objectForKey:#"fontSize"] floatValue];
fontName = [dictionary objectForKey:#"fontName"];
//now rebuild color and font like this:
UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1];
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
}
Hope this helps.
BTW: If you find the answer useful , mark it as correct.
Cheers,
George

How to check the latest version of the app with NSUserDefaults

I want to check if user is using the latest version of the app. If so, i should color the background of some cells.
This is the code i'm using:
appDelegate.m
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastVer"];
method where i want to check:
NSString *lastVersion = (NSString *) [[NSUserDefaults standardUserDefaults] objectForKey:#"lastVer"];
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
lastVersion = #"1.3.4";
if(![lastVersion isEqualToString:version]){
cell.backgroundColor = [UIColor yellowColor]; ;
cell.imageView.image = [UIImage imageNamed:#"image.png"];
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
}
Am i doing it right? Is my code checking for the latest version or? How can i simulate this behavior in the simulator \ on device?
What i want to do is check if the user is using the latest version of the app, in order to call in another NSUserDefaults key to show the cells of my tableView with a different background color.
EDIT
Code i'm using to change the cells background if the user is using the latest version of my app and if the user has used the app less than three times:
NSString *cellValue = cell.textLabel.text;
NSNumber *runNumber = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:#"runNum"];
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastVer"];
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
if (!runNumber) {
runNumber = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject:runNumber forKey:#"runNum"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
if([lastVersion isEqualToString:version]){ //check if the user is using the latest version
if ([runNumber intValue] < 4) { //check if user has used the app less than 3 times
if ([cellValue isEqual: "someText"] ){
cell.backgroundColor = [UIColor yellowColor]; ;
cell.imageView.image = [UIImage imageNamed:#"image.png"];
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
}
}
this code will not set anything..
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastVer"];
lastVersion = #"1.3.4";
you need a setter:
[[NSUserDefaults standardUserDefaults] setObject: #"1.3.4" forKey:#"lastVer"];//in memory
[[NSUserDefaults standardUserDefaults] synchronize];//to disk
and a getter:
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastVer"];
edit:
remember that lastVersion is a pointer and you just set it to point somewhere else, that doesn't set it in stdUserDefaults and it doesn't synchronize it to disk.
Surely if you want to check if the user is using the latest version of the app you would need to check with an external resource.
e.g.
Simple HTTP request to your own server, which returns your latest app version.
Then compare this against your current version [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
Store the result of this test in NSUserDefaults