I am creating dynamically some "n" number of UIView Object in my application.I can able to drag, drop these objects to any position in the screen & chenge change their some of property .Now i want to save all these details with persistance storage ,so that whenever i launched the application nest time, i can able to see those already created object.
So what is the best solution for this?
Also is their any sample application available for this form which i can take reference?
I think you can do it this way.
// Create an array to store the properties
NSMutableArray *viewProperties = [NSMutableArray array];
// Loop through all the views
for (UIView *view in views) {
// Create a dictionary for each view
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// Store the properties in the dictionary
[dict setValue:NSStringFromCGRect(view.frame) forKey:#"ViewFrame"];
...
// Add the dictionary to the array
[viewProperties addObject:dict];
}
// Finally add the array to persistence
[userDefaults setValue:viewProperties forKey:#"ViewProperties"];
Later you can get the array from persistence and create the views with the properties.
NSMutableArray *viewProperties = [userDefaults valueForKey:#"ViewProperties"];
for (NSDictionary *dict in viewProperties) {
UIView *view = [[UIView alloc] init];
NSString *frameAsString = [dict valueForKey:#"ViewFrame"];
view.frame = CGRectFromString(frameAsString);
// Get other properties from dictionary and set it to view
}
Related
I just learned how to make use of KVO, but only the basics. What I need to achieve is something like this:
I have a delegate call that passes a Speaker object.
- (void)onSpeakerFound:(Speaker *)speaker
Once I receive this Speaker in the UI part, from there I will assign observers for this object.
But, this is just for one speaker. What if I have multiple speakers to keep track of. I need to assign observers separately for those speakers and then at the same time I wish to keep their references for further updates to the values.
Each speaker could be updated from time to time. So when I notice that there is a change that happened on a speaker, I wish to access the reference to that speaker and update the values just like how NSMutableDictionary works.
NSMutableDictionary makes a copy of an object set to it so it will be a difference object if I get it again from the dictionary.
So, is there a class that allows me to keep track of an object by just keeping a reference only to that object without making a copy of it?
EDIT: A Test Made To Verify That When An Instantiated Object is Set in an NSMutableDictionary, The Instantiated Object is not referenced with the one set inside NSMutableDictionary.
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSString *obj = #"initial value";
NSString *key = #"key";
[dict setObject:obj forKey:key];
NSLog(#"Object is now %#", [dict objectForKey:key]);
obj = #"changed value";
NSLog(#"Object is now %#", [dict objectForKey:key]);
}
Log:
2016-07-26 21:04:58.759 AutoLayoutTest[49723:2144268] Object is now initial value
2016-07-26 21:04:58.761 AutoLayoutTest[49723:2144268] Object is now initial value
NSMutableDictionary makes a copy of an object set to it...
That is not correct; it will add a reference to the object. It will be the same object referenced inside and outside the Objective-C collection.
So, is there a class that allows me to keep track of an object...?
Probably NSMutableSet if you just want a list of the objects. That will take care that you have a unique reference to each object, however you need to implement the methods hash and isEqual on those objects so they behave correctly. Otherwise NSMutableDictionary if you want fast look-up by key.
-try this one
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSString *obj = #"initial value";
NSString *key = #"key";
[dict setObject:obj forKey:key];
NSLog(#"Object is now %#", [dict objectForKey:key]);
obj = #"changed value";
[dict setObject:obj forKey:Key];
NSLog(#"Object is now %#", [dict objectForKey:key]);
}
I am trying to create shopping cart. I want to put all data NSMutableDictionary from NSDictionary with Bar-code number which has DataItem variable as key. I have created NSMutableDictionary with that code block;
- (void)viewDidLoad {
[super viewDidLoad];
DataItem = [[[_response objectForKey:#"Data"] objectForKey:#"Items"] objectForKey:#"Item"];
NSMutableDictionary *CartItems = [[NSMutableDictionary alloc]init];
for(NSDictionary *transaction in DataItem)
{
[CartItems setValue:transaction forKey:[transaction objectForKey:#"BarcodeNumber"]];
}
}
When I push another viewController for selection another item to put cart. Once again,push that viewController, it deletes before item from CartItems variable.
I know I have putted that code block NSMutableDictionary *CartItems = [[NSMutableDictionary alloc]init]; inside of viewDidLoad. That's why, It generates new CartItems variable. If I want to put it .h file, it returns nil. I did not find any solution.
Is there any way to load data to NSMutableDictionary for reusing? or Is there another way to create same logic? Thanks.
use a singleton class to store you data like this tutorial
Make a singleton class for data which returns same object with first time initialization and use that for storing your data.
+ (id)getBE {
static MyBEClass *objMyBEClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
objMyBEClass = [[self alloc] init];
});
return objMyBEClass;
}
Make CarItems dictionary a property of BE class so you can get this from your view controller.
#property(strong)NSMutableDictionary *CartItems;
In init method of BE class initialize your array/dictionary.
CartItems = [[NSMutableDictionary alloc]init];
You can manage this by using NSUserDefaults. Here is viewDidLoad-
- (void)viewDidLoad {
DataItem = [[[_response objectForKey:#"Data"] objectForKey:#"Items"] objectForKey:#"Item"];
NSUserDefaults *prefrence=[[NSUserDefaults alloc]init];
if ([[NSUserDefaults standardUserDefaults]objectForKey:#"cartItems"]!=nil) {
NSMutableDictionary *CartItems=[[NSUserDefaults standardUserDefaults]objectForKey:#"cartItems"];
for(NSDictionary *transaction in DataItem)
{
[CartItems setValue:transaction forKey:[transaction objectForKey:#"BarcodeNumber"]];
}
[prefrence setObject:CartItems forKey:#"cartItems"];
}else{
NSMutableDictionary *CartItems = [[NSMutableDictionary alloc]init];
for(NSDictionary *transaction in DataItem)
{
[CartItems setValue:transaction forKey:[transaction objectForKey:#"BarcodeNumber"]];
}
[prefrence setObject:CartItems forKey:#"cartItems"];
}
}
whenever you want to clear your cart that time also clear NSUserDefaults using [[NSUserDefaults standardUserDefaults]removeObjectForKey:#"cartItems"].
I would not suggest to use a Singleton for such a thing except if your building a huge app with many controllers, and you need your chart everywhere.
If it's not the case, I would suggest you to pass the char as parameter from one controller to the other one, and pass it back with a delegate as in this guide.
if you have an application built with a single navigation controller, remember that it is not deallocated, so you can save data there. Just make getters and setters of your variable visible (.h file) or the variable itself, but remember that that is not a very good practise because it looks like it will be modified by many controllers, and thats another reason why you should avoid using singletons.
Hope it helps!
I am trying to iterate through a NSDictionary and add all the values in that dictionary to an object. So i added new cocoa class file to my project and subclassed it with NSObject. (named it customClass)
In my custom class.h:
- (void)printDir; // iterate through the direcory and print it.
#property (nonatomic, retain) NSMutableDictionary *objDictionary;
In customClass.m the defination of printDir method is as:
- (void)printDir {
_objDictionary = [[NSMutableDictionary alloc ]init];
for(id key in _objDictionary) {
id value = [_objDictionary objectForKey:key];
NSLog(#"Values in Objects Dictionary");
NSLog(#"%#",value);
}
}
In my ViewController.m i am trying to iterate through a NSDirectory and add all the values of that directory to the NSMutableDictionary of the object. For which,
for(id key in jsonDictionary.allKeys) {
id value = [jsonDictionary objectForKey:key];
[obj.objDictionary setObject:value forKey:key];
}
When i run the project the printDir method of the object get called, however the for loop does not execute. Can someone point out where i am going wrong. Thanks.
_objDictionary = [[NSMutableDictionary alloc ]init];
Change this line in your printDir method to init method of your custom class. The problem now is each time when you reach your printDir method, it is re-assigning the _objDictionary to nil. So the loop will not execute
In printDir Function you are allocating a dictionary objDictionary again.... so it over right your actual value supplies by your view controller .... You just change your function to this
In .h file
- (void)printDirwithDictionary :(NSMutableDictionary *)dict;
And in .m file
- (void)printDirwithDictionary:(NSMutableDictionary *)dict {
_objDictionary = [[NSMutableDictionary alloc] initWithDictionary:dict]
for(id key in _objDictionary) {
id value = [_objDictionary objectForKey:key];
NSLog(#"Values in Objects Dictionary");
NSLog(#"%#",value);
}
}
In ViewController.m Follow This code
NSMutableDictionary *dictToPass = [[NSMutableDictionary alloc]init];
for(id key in jsonDictionary.allKeys) {
id value = [jsonDictionary objectForKey:key];
[dictToPass setObject:value forKey:key];
}
[obj printDirWithDictionary:dictToPass];
And Call from View Controller will be like this
And Then Follow the sameprocedure . Hope This will Work Properly .
I figured the way to do this was to create the main dictionary (called mainDictionary), and then have another dictionary (called tempDictionary) and fill up tempDictionary one with the values as I get them. Then, add tempDictionary as a value into the main dictionary. This works, but then I need to clear tempDictionary so that I can refill it again, and then add that as another value in the main dictionary. The thing is, when I clear tempDictionary, it also erases those values from the main dictionary. Here's my code:
NSMutableDictionary *tempDictionary = [[NSMutableDictionary alloc]init];
[tempDictionary setObject:#"apple" forKey:#"myFruit"];
[mainDictionary setObject:tempDictionary forKey:#"sample4"];
[tempDictionary removeAllObjects];
So apparently I need to use a different method, or somehow "save" the mainDictionary before clearing tempDictionary. The tempDictionary needs to be dynamically updated and then fill the mainDictionary.. is there a way to do this? There will be hundreds of "samples" that need to be added, so I can't just have a bunch of tempDictionarys created at runtime.
If you want the temp dictionary contents (as added to main) to remain intact when you remove all the objects from the temp dictionary you should copy it before adding it to the main dictionary.
NSMutableDictionary *tempDictionary = [[NSMutableDictionary alloc] init];
[tempDictionary setObject:#"apple" forKey:#"myFruit"];
[mainDictionary setObject:[tempDictionary copy] forKey:#"sample4"];
[tempDictionary removeAllObjects];
The alternative is to reuse tempDictionary but to do
tempDictionary = [NSMutableDictionary dictionary];
to create a new temp dictionary with the same name every time you begin a new collection - this is very different to
[tempDictionary removeAllObjects];
I'm working with a plist file at the moment but intend to switch over to json when the backend is finally built. So for the moment my plist is an array that contains a bunch of dictionaries.
I'd like to use this information to create a new array containing only the dictionaries with certain values.
For example. My plist contains a bunch of locations like so:
key: location value:example place name here
key: type value:indoor
I want to build an array containing only those with "indoor" set as the type value.
And then perhaps a second one containing all "outdoor" locations.
What's the best way to go about doing this, or perhaps I can be directed to a tutorial of some sort.
Thanks.
Simply loop through your array and add the qualifying dictionaries to a new array.
NSMutableArray *arrayIndoor = [NSMutableArray array];
NSMutableArray *arrayOutdoor = [NSMutableArray array];
NSString *type;
for (NSDictionary *dict in arrayPList) {
type = [dict objectForKey:#"type"];
if ([type isEqualToString:#"indoor"])
[arrayIndoor addObject:dict];
else if ([type isEqualToString:#"indoor"])
[arrayOutdoor addObject:dict];
}
All you are really needing to do is sort the array into two arrays. There isn't a direct method that I have seen that will do this for you. My suggestion would be to use a fast enumeration over the array and conditionally break it into two new arrays.
NSMutableArray *locations = [[NSMutableArray alloc] init];
NSMutableArray *type = [[NSMutableArray alloc] init];
for (NSDictionary *dict in MyPlistArray) {
if ([dict valueForKey:#"locationKey"]) {
[locations addObject:dict];
} else if ([dict valueForKey:#"typeKey"]) {
[type addObject:dict];
}
}
You might need to use a different method for determining which key to put in each array, but you get the general idea.
Also I'm assuming that you would want the arrays of dictionaries to persist after, so you can just set those up as properties instead of local variables.