Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I agree with most of the answers that <code>NSDictionary</code> should be accessed with <code>objectForKey:</code> or similar methods. However it is possible to allow for dot notation access to a <code>NSDictionary</code>, and for learning purposes this might be interesting for someone. Also when for example your are retrieving large JSON dictionaries via <code>AFNetworking</code>, this method can ease the access and readability of your code.</p> <p>This is my solution:</p> <p>DictionaryProperties.h: (class wrapping the NSDictionary for property access)</p> <pre><code>@interface DictionaryProperties : NSObject{ NSMutableDictionary* _backingDict; } @property (nonatomic, strong) NSMutableDictionary* backingDict; + (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict; @end </code></pre> <p>DictionaryProperties.m:</p> <pre><code>#import "DictionaryProperties.h" @implementation DictionaryProperties @synthesize backingDict = _backingDict; - (id) initWithDictionary:(NSDictionary*)dict { if (self) { if ([dict isKindOfClass:[NSMutableDictionary class]]) { self.backingDict = (id)dict; } else { self.backingDict = [[NSMutableDictionary alloc] initWithDictionary:dict]; } } return self; } + (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict { return [[DictionaryProperties alloc] initWithDictionary:dict]; } - (void)forwardInvocation:(NSInvocation *)invocation { NSString* key = NSStringFromSelector(invocation.selector); invocation.selector = @selector(objectForKey:); [invocation setArgument:&amp;key atIndex:2]; if ([self.backingDict objectForKey:key]) { [invocation invokeWithTarget:self.backingDict]; } else { [self doesNotRecognizeSelector:invocation.selector]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ return [self.backingDict methodSignatureForSelector:@selector(objectForKey:)]; } @end </code></pre> <p>ExampleDictContent.h: (class declaring what is inside the dictionary)</p> <pre><code>#import "DictionaryProperties.h" @interface ExampleDictContent : DictionaryProperties @property (strong, nonatomic) NSString* someData; @property (strong, nonatomic) NSString* someOtherData; @end @implementation ExampleDictContent @end </code></pre> <p>Usage: (simple declaration of a dictionary, allocation of wrapper and property access)</p> <pre><code>#import "ExampleDictContent.h" NSDictionary* d = [NSDictionary dictionaryWithObjects:NSArray arrayWithObjects:@"someData content", @"someOtherData content", nil forKeys:NSArray arrayWithObjects:@"someData", @"someOtherData", nil]; ExampleDictContent* dictWProps = [ExampleDictContent allocWithDictionary:d]; NSLog(dictWProps.someData); NSLog(dictWProps.someData); </code></pre> <p>This will print:</p> <pre><code>someData content someOtherData content </code></pre> <p>So basically <code>DictionaryProperties</code> works as a facade for accessing the <code>NSDictionary</code>. It uses <code>forwardInvocation</code> to convert a <code>get-property</code> method call into a <code>getObjectForKey:</code> call on the dictionary. What I like about it, is that it allows for autocompletion on the dictionary, and also allows me to explicitly declare what keys I want to access (in the <code>ExampleDictContent.h</code> file). Note that this solution does not allow for write access to the properties, but that can be added as shown in the link below.</p> <p>This solution has partly been inspired by <a href="https://blog.compeople.eu/apps/?p=452" rel="nofollow">karstenlitsche's solution</a>. The main difference is that this solution is based on sub-classing instead of categories. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload