Iterate over key values in a Restkit Model - objective-c

I'm guessing there is a simple solution here, but I've tried some things and nothing seems to work out. What I'd like to do is be able to iterate through the stored values in a model so I can present them in different ways graphically.
I can access the web service and store the data perfectly. As part of a larger model, I have a goals model with various goals that can be set.
GoalsModel looks like
#class RoundGoalsModel;
#interface RoundGoalsModel : NSObject {
NSNumber* _scoreGoal;
NSNumber* _parsGoal;
NSNumber* _birdiesGoal;
}
#property (nonatomic, retain) NSNumber* scoreGoal;
#property (nonatomic, retain) NSNumber* parsGoal;
#property (nonatomic, retain) NSNumber* birdiesGoal;
#end
All the data is in there as expected. Now all I need to do is figure out how to loop through the keys and values in the Model so I can do things like present different icons for different goals, check if a value is null, etc. I'm trying to avoid having to access each individually with a bunch of conditional statements.
I've tried casting it to an array and other things that dont seem to work. Any advice or suggestions pointing me in the right direction would be awesome. Thanks!

Your problem isn't a RestKit problem it's just an issue with your design. Since you already have your data placed into the individual fields you could just add a new field to return them in an array.
.h
#property(readonly, retain)NSDictionary *allProperties;
.m
#synthesize allProperties;
- (NSDictionary*)allProperties
{
return [NSDictionary dictionaryWithObjectsAndKeys: _scoreGoal, #"scoreGoal", _parsGoal, #"parsGoal", _birdiesGoal, #"birdiesGoal", nil];
}
Then you could easily iterate over the dictionary and do whatever you want.

Related

#property (weak, nonatomic) or #property (nonatomic, weak)? Which one closest to Apple guidelines?

If I look at UIViewController.h, I can see atomicity before retainability:
#property(nullable, nonatomic, readonly, strong) NSBundle *nibBundle;
As if I drag an drop an element from a .xib to a counterpart file, it generates retainability before atomicity:
#property (weak, nonatomic) IBOutlet UIView *testView;
Source: Xcode 7 beta 5.
Which one is recommended or following Apple guidelines more closely?
Which one is recommended or following Apple guidelines more closely?
The order of the attributes is unimportant, and I'm not aware of any guidelines regarding the order. Personally, I usually put the atomicity specifier at the end because it's almost always the same and the thing I care least about. A good friend puts it first because it's easiest to skip when all the nonatomic specifiers line up. Do what you like best.
Edit to the comments:
I tried it with:
NSPredicate *propertyPredicate = [NSPredicate predicateWithFormat:#"kind = %d", CXCursor_ObjCPropertyDecl];
NSMutableDictionary *properties = [NSMutableDictionary new];
[protocol visitChildrenMatchingPredicate:propertyPredicate withBlock:
^(CLNGEntity *property, CLNGEntity *parent)
{
CXCursor cursor = property.cxCursor;
CXType type = clang_getCursorType(cursor);
CXString spelling = clang_getTypeSpelling(type);
const char *cSpelling = clang_getCString(spelling);
NSLog(#"Property type %s", cSpelling);
return CXChildVisit_Continue;
}];
(Don't care about the CLNG… types, they are simple Objective-C wrappers around the corresponding CX… types. The only additional capability used here is the possibility to visit blocks matching an NSPredicate instance.)
However, with this code I only get the spelling of the type of the property, i. e. …:
2015-09-16 10:18:33.689 obcl_cloudInterfaceExporter[1544:507] Property type NSString *
… but not the complete property declaration. But I would bet that there was a function to print (dump) the whole cursor. But I cannot find it now. Sorry. (Maybe it was in the C++ API only, but later I decided to switch to the C API.)
However, since you are working on clang, you will have better chances to find it, if I do not remember that completely wrong.

How to get values from an NSArray after applying filter to NSArrayController in Cocoa

I'm learning bindings in cocoa. My ArrayController is bound to a tableview and a searchfield. data display and filtering is fine.
These properties are in the mutableArray.
#property (nonatomic, strong) NSString *displayName;
#property NSInteger entityID;
#property (nonatomic, strong) NSString *MemberStatus;
In the table, I'm displaying the 'displayName'. My main problem is, I need to select a row and run an webservice using 'entityID' of that selected member.
If I do not filter and select a row, I'm able to fetch the needed 'entityID' from the mutable array using selected row index.
[[[self.participantArray objectAtIndex:selectedRow] valueForKey:#"entityID"] integerValue]
Whenever I'm filtering, depending on the selected row index it is returning wrong values naturally. How do I get the correct fields? Please help. If my question is not clear, please mention what you need.
thanks.
The table view is displaying the arrangedObjects of the array controller. So, you should index into that, too.
You will need an outlet to the array controller so that you can do something like:
[[[self.particpantsController.arrangedObjects objectAtIndex:selectedRow] valueForKey:#"entityID"] integerValue]
(I'm actually not sure why you're using -valueForKey: here. The expression [self.particpantsController.arrangedObjects objectAtIndex:selectedRow] gives you the object. If it has an entityID property, you can just call the getter on that object. If it's an NSDictionary, then you should prefer -objectForKey: over -valueForKey:. Well, actually, you should prefer creating a real model object class and using that rather than NSDictionary. Making dictionaries tends to work well in toy apps and prototyping, but quickly shows its limits.)

Storing any number of different classes in one property

I have a collection of instances of different classes (9 to be precise), all with identical methods and properties, but each one performs a specific task.
I want to be able to switch between these different objects at any point. There maybe times when only a few of the objects get used, sometimes when they all get used, and other times when only one is used.
Ideally, I want a single property that could point to an instance of any of these objects. Ive tried doing something like this:
#property (nonatomic, strong) id * currentObj;
...
currentObj=[[ClassType3 alloc] init];
(ClassType3 is just one of the 9 different classes, in this example they go from ClassType1 to ClassType9)
But that doesn't work, I get these two warnings:
Property with 'retain (or strong)' attribute must be of object type.
Pointer to non-const type 'id' with no explicit ownership.
My question is, can something like this be achieved, or do I need to create an instance of each class just in case it needs to be used?
Gabriele gave already a correct answer. However,
if all the classes have identical methods and properties, you should consider to
make all classes inherit from a common superclass, and declare the property as
#property (nonatomic, strong) SuperClass * currentObj;
OR define a #protocol which comprises the common methods/properties, make all
classes conform to that protocol, and declare the property as
#property (nonatomic, strong) id <YourProtocol> currentObj;
The advantage in both cases is that the compiler can do more/better error checking when
the property is assigned or used.
id is already a pointer.
Change
#property (nonatomic, strong) id * currentObj;
to
#property (nonatomic, strong) id currentObj;
Moreover, please use capitalized names for classes.

Possible to set multiple parent entities for Core Data NSManagedObject?

I have created the following example Core Data NSManagedObject subclasses:
PBCommentableObject : NSManagedObject // to allow comments on object
#property (nonatomic, retain) NSSet *pBcomments; // unordered set of PBComment objects
PBComment : PBCommentableObject // to allow comments on a comment
#property (nonatomic, retain) PBCommentableObject *target;
PBList : PBCommentableObject // to allow comments on a list
#property (nonatomic, retain) NSOrderedSet *pBorderedItems; // ordered set of PBListableObject objects
PBString : PBListableObject // to allow strings to be added to lists
#property (nonatomic, retain) NSString *pBtext;
PBListableObject : ???? // I'd like both PBList and PBString to be PBListableObjects
#property (nonatomic, retain) PBList *pBlist;
The problem I am having is that I would like the following behavior:
Lists (PBList) that can hold an ordered list of strings (PBString) or other lists (PBList).
Allow comments (PBComment) on lists (PBList) and other comments (PBComment) but not strings (PBString)
Is this possible to do? I am currently trying to build the Core Data model via the visual interface in Xcode; and while I could conceive of using categories, I don't know how I would do so without Xcode spitting out a warning when I fail to define a relationship via the visual editor.
I think you are stretching the idiom of inheritance. All this "listable" and "commentable" results in quite unreadable complexity.
The validation of allowing or disallowing comments, lists or what have you, can be modeled with simply using (boolean) attributes and relationships. Try to think of only concrete objects such as "Comment" or "String" and model the lists with the attribute sets.

How to model an n-to-n relationship in Objective-C?

I am trying to model an n-to-n relationship in Objective-C. Suppose I have two entities: Movie and Theater. A Movie has an array of Theaters and a Theater has an array of Movies. How do I do this in Objective-C to 1) get the relationship correct and 2) make sure memory is managed correctly.
On Apple platforms you have access to Core Data, a very nice persistence framework.
You can use SQLLitePersistentObjects:
It allows you to define code like the following:
#import "SQLLitePersistentObjects.h"
#interface CFCategory : SQLLitePersistentObject {
NSString *name;
CFRegion *region; // where region is another subclass of SQLLitePersistentObject
}
#property(nonatomic, retain, readwrite) NSString *name;
#property(nonatomic, retain, readwrite) CFRegion *region;
#end
And use it in your code:
CFRegion *region = [CFCategory findByRegion:[myRegionObject pk]];
Memory and persistence is automatically handled by the framework. However, if you are working with large data sets be sure to use NSArray objects with the paired arrays functionality instead of allocating and deallocating hundreds or thousands of SQLLitePersistentObjects.