Property List with 8 Types Challenge - how to parse Plist?


#1

This is my solution. Though it meets the challenge, I am still puzzled like many here on how to properly distinguish objects within a plist for reading. Specifying id type with fast enumeration does not yield specific object types, but the entire array of objects instead. My thinking was to use fast enumeration and discern each object type before logging as shown here but it does not work (it catches an exception), I believe because the methods (e.g. integerValue or floatValue) are being sent to ALL objects and not NSNumber type objects specifically. If anyone can shed some light on how to properly parse through a plist it would be most welcomed!

Parsing through a plist (FAILED!)

[code] // READ Plist
NSArray *inputPlist = [NSArray arrayWithContentsOfFile:@"/tmp/aPropertyList.plist"];
for (NSNumber *a in inputPlist) {
if (a.integerValue) {
NSLog(@“Here’s are some integers: %ld”, a.integerValue);
}

            if (a.floatValue) {
                NSLog(@"Here are some floats: %f", a.floatValue);
            }
            
            if (a.boolValue) {
                NSLog(@"Here is a BOOL: %hhd", a.boolValue);
            }
            
        for (NSString *s in inputPlist) {
                NSLog(@"Here are some strings: %@", s);
            }
            
        for (NSMutableArray *a in inputPlist) {
                NSLog(@"Here are some arrays: %@", a);
            }
            
        for (NSArray *a in inputPlist) {
                NSLog(@"Here's an array: %@", a);
            }

        }[/code] Obviously an inexperienced attempt.  There must be a better way...

Challenge Solution:

[code]//
// main.m
// ObjC_PropertyLists_with-all-8-datatypes - Challenge
//

#import <Foundation/Foundation.h>

/// PROPERTY LISTS - writing a Property list that has all 8 types in it: array, dictionary, string, data, date, integer, float, and boolean ///

int main(int argc, const char * argv[]) {
@autoreleasepool {

    // BUILD a container aray to house the various objects
    //NSMutableArray *mainArray = [NSMutableArray alloc];

    // an Array
    NSArray *anArray = @[@"string1", @"string2", @"string3"];
    
    // a Dictionary (literal) with various object types
    NSDictionary *aDictionary = @{ @"aFloat" : @1.2,
                                  @"anInteger1" : [NSNumber numberWithInt:122],
                                  @"anInteger2" : @65,
                                  @"aString" : @"Hello World",
                                  @"anArray" : @[@"Yellow", @"Red", @"Blue"],
                                  };
    
    // a String
    NSString *aString = @"This is a String";
    
    // a Date
    NSDate *aDate = [NSDate date];
    
    // an Integer
    NSNumber *anInt = @10;
    
    // a Float
    NSNumber *aFloat = [NSNumber numberWithFloat:3.1345];
    
    //a BOOLean
    NSNumber *aBool = [NSNumber numberWithBool:YES];
    
    // an NSData
    NSData *aData = [NSData dataWithContentsOfFile:@"/tmp/nsdatadummy.log"];
    
    // an NSString
    NSString *aStringFromData = [[NSString alloc] initWithData:aData encoding:NSUTF8StringEncoding]; // string with data (used to display nsdata as string instead of hex)
    
    
    // ADD ALL objects TO array container
    NSMutableArray *mainArray = [[NSMutableArray alloc] initWithObjects:anArray, aDictionary, aString, aDate, anInt, aFloat, aBool, aData, aStringFromData, nil];
    
    
    // WRITE array container to plist
    BOOL written = [mainArray writeToFile:@"/tmp/aPropertyList.plist" 
                atomically:YES];
    
    if (!written) {
        NSLog(@"Plist not written, exiting..");
        return 1;
    }

    // READ Plist
    NSArray *inputPlist = [NSArray arrayWithContentsOfFile:@"/tmp/aPropertyList.plist"];
    NSLog(@"%@", inputPlist);

        

    
        }


return 0;

}[/code]


#2

[quote]Parsing through a plist (FAILED!)

Obviously an inexperienced attempt. There must be a better way…
[/quote]
Here is an easy way: Put all objects into a dictionary with carefully selected keys, one for each object. Then, save that dictionary object as a property list. When you read it back in, you know exactly what to look for because you know the keys.

[Become a competent programmer faster than you can imagine: pretty-function.org]


#3

So this would mean using a dictionary instead of a mutable array to encapsulate the various objects within the plist. While certainly one way to go about it, seems rather manual and work intensive.

  1. is there no way to enumerate objects based on type while iterating over an plist-populated array or otherwise? Isn’t fast enumeration supposed to filter the enumeration based on the specified object type eg: for(NSNumber *n in pListArray). In this case, fastenumeration returns ALL objects in the array and not just the specified type in the enumeration.

  2. if #1 is not possible (would like to understand why) what would be the methodology for automatically reading objects off of a plist based on “x” criteria (object type, etc) without needing to identify specific keys?

Thx for the insight!