Widgets Exercise 15.5
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 28, 2015, 02:29:21 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Programming in Objective-C, 4th edition
| |-+ Exercises
| | |-+ Chapter 15
| | | |-+ Exercise 15.5
Pages: [1] Go Down
Author Topic: Exercise 15.5 (Read 831 times)
Posts: 2


on: February 19, 2012, 12:08:35 PM

Hi -

I am trying to change my lookup method to be able to search for a string through out all my address card fields without knowing explicitly what those object properties are.  I created an array with the addressCard properties that is passed into lookup.  Obj C does not like that I am trying to tell it to get a property through a variable name.  Is there a way to get a list of the properties for an object and then dynamically iterate through the object properties?

Let me know or tell me a better way to approach this.  Thanks,  Terry

// Look up card in address book
- (AddressBook *) lookup: (NSString *) theSubString for: (NSArray *) theProperty
    NSRange subRange;
    AddressBook *bookLookup = [[AddressBook alloc] initWithName: @"Lookup Address Book"];
    NSString *theName;
    NSUInteger i = 0, max = [theProperty count];
    for (i = 0; i == max; ++i){
        theName = [theProperty objectAtIndex: i];
    for (Address_Card *nextCard in book)
        subRange = [nextCard.theName rangeOfString: theSubString];
        if(subRange.location != NSNotFound)
            [bookLookup addCard: nextCard];
    return bookLookup;
    else return nil;
Posts: 28

Reply #1 on: February 26, 2012, 06:43:59 PM

I used a similar approach, except I used an NSMutableDictionary to store the variables in the AddressCard (one instance variable), the keys being the variable names, and the objects storing the values (both NSString).  That way I can enumerate over all the key-object pairs from AddressBook without AddressBook knowing what all those fields are.

This seems to work great, but I had to change both my AddressBook and AddressCard classes quite a bit to work with the dictionary rather than the independent instance variables.  Is there a better way to enumerate over the instance variables of an object?

Here's my lookup method:
Code: (Objective-C)
-(NSMutableArray *) lookupAll: (NSString *) theName
    //Find indexes in the address book that match the search term
    NSIndexSet *indexResults = [book indexesOfObjectsPassingTest:
        ^(id obj, NSUInteger idx, BOOL *stop) {
            NSRange subrange;
            NSMutableDictionary *theProperties = [obj myProperties];
            //Enumerate over all properties in the current AddressCard dictionary
            for (id key in theProperties)
                subrange = [[theProperties objectForKey:key] rangeOfString:theName options:NSCaseInsensitiveSearch];
                if (subrange.location != NSNotFound)
                    return YES;
            // Nothing found.
            return NO;
    NSMutableArray *cardsResults;
    //Put the found address cards into an array using their indexes.
    if ([indexResults count] > 0)
        cardsResults = [NSMutableArray array];
        [indexResults enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
            [cardsResults addObject:[book objectAtIndex:idx]];
    return cardsResults;
Posts: 1

Reply #2 on: March 10, 2012, 11:15:55 AM

another slution  Wink
Addresscard composited from name and email and address =( unsigned long zip ,NSString city, NSString state ,NSString country) !

code for searchAll

-(NSIndexSet *)searchAll:(NSString *)string
    NSIndexSet *result = [book indexesOfObjectsPassingTest:
                          ^BOOL(id obj, NSUInteger idx, BOOL *stop)
                              NSRange nameRange = [[obj name] rangeOfString:string options:NSCaseInsensitiveSearch];
                              NSRange emailRange =[[obj email] rangeOfString:string options:NSCaseInsensitiveSearch];
                              Address *pes = [obj PersonAddress];
                              NSRange cityRange = [[pes city] rangeOfString:string options:NSCaseInsensitiveSearch];
                              NSRange stateRange = [[pes state] rangeOfString:string options:NSCaseInsensitiveSearch];
                              NSRange countryRange =[[pes country] rangeOfString:string options:NSCaseInsensitiveSearch];
                              if (nameRange.location != NSNotFound)
                                  return YES;
                              else if (emailRange.location != NSNotFound)
                                  return YES;
                              else if ([pes zip] ==(long) [string integerValue])
                                  return YES;
                              else if (cityRange.location !=NSNotFound)
                                  return YES;
                              else if (stateRange.location !=NSNotFound)
                                  return YES;
                              else if (countryRange.location !=NSNotFound)
                                  return YES;
                                  return NO;
    return result;
Pages: [1] Go Up
Jump to:

Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 All rights reserved.