views:

210

answers:

1

First off I am very new to Objective C and iPhone programming. Now that that is out of the way. I have read through most of the Apple documentation on this and some third party manuals.

I guess I just want to know if I'm going about this the correct way ...

- (NSMutableArray *)makeModel {

    NSString *api = @"http://www.mycoolnewssite.com/api/v1";

    NSArray *namesArray = [NSArray arrayWithObjects:@"News", @"Sports", @"Entertainment", @"Business", @"Features", nil];

    NSArray *urlsArray = [NSArray arrayWithObjects:
                      [NSString stringWithFormat:@"%@/news/news/25/stories.json", api],
                      [NSString stringWithFormat:@"%@/news/sports/25/stories.json", api],
                      [NSString stringWithFormat:@"%@/news/entertainment/25/stories.json", api],
                      [NSString stringWithFormat:@"%@/news/business/25/stories.json", api],
                      [NSString stringWithFormat:@"%@/news/features/25/stories.json", api], nil];

    NSMutableArray *result = [NSMutableArray array];

    for (int i = 0; i < [namesArray count]; i++) {
        NSMutableDictionary *objectDict = [NSMutableDictionary dictionary];
        NSString *name = (NSString *)[namesArray objectAtIndex:i];
        NSString *url = (NSString *)[urlsArray objectAtIndex:i];
        [objectDict setObject:name forKey:@"NAME"];
        [objectDict setObject:url forKey:@"URL"];
        [objectDict setObject:@"NO" forKey:@"HASSTORIES"];
        [result addObject:objectDict];
    }

    return result;
}

The output of the result is ...

(
    {
    HASSTORIES = NO;
    NAME = News;
    URL = "http://www.mycoolnewssite.com/api/v1/news/news/25/stories.json";
},
    {
    HASSTORIES = NO;
    NAME = Sports;
    URL = "http://www.mycoolnewssite.com/api/v1/news/sports/25/stories.json";
},
    {
    HASSTORIES = NO;
    NAME = Entertainment;
    URL = "http://www.mycoolnewssite.com/api/v1/news/entertainment/25/stories.json";
},
    {
    HASSTORIES = NO;
    NAME = Business;
    URL = "http://www.mycoolnewssite.com/api/v1/news/business/25/stories.json";
},
    {
    HASSTORIES = NO;
    NAME = Features;
    URL = "http://www.mycoolnewssite.com/api/v1/news/features/25/stories.json";
}
)

Any insight would be appreciated ;-)

+3  A: 

It looks fine. There can be some minor improvements if you care.

1.

[NSString stringWithFormat:@"%@/news/news/25/stories.json", api]

can be replaced by

[api stringByAppendingString:@"/news/news/25/stories.json"]

if there's no chance the api appears in the middle or accepts other arguments.

2.

    NSString *name = (NSString *)[namesArray objectAtIndex:i];
    NSString *url = (NSString *)[urlsArray objectAtIndex:i];

The explicit cast is unnecessary. An id can be implicitly casted to and from other ObjC objects.

3.

You could use a convenient method -dictionaryWithObjectsAndKeys: to construct the dictionary in one-shot, so you don't need a temperary dictionary:

[result addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
   name, @"NAME",
   url, @"URL",
   @"NO", @"HASSTORIES", nil]];

4. (optional)

This transform is not useful if the function is not a hot spot.

Since the arrays are only used locally, it's more efficient to use a C array.

static const int arraySize = 5;
NSString* namesCArray[] = {@"News", @"Sports", @"Entertainment", @"Business", @"Features"};
NSString* urlsCArray[arraySize];
urlsArray[0] = [api stringByAppendingString:@"/news/news/25/stories.json"];
...
for (int i = 0; i < arraySize; ++ i) {
  ...
  NSString* name = namesCArray[i];
  NSString* url = urlsCArray[i];
  ...
}

this removes the repeated -count and -objectAtIndex: calls which is very slow compared with direct element access.

5. (optional)

This transform is not useful if the array is short.

You could use fast-enumeration to loop over an ObjC container:

int i = 0;
for (NSString* name in namesArray) {
  NSString* url = [urlsArray objectAtIndex:i];
  ...
  ++ i;
}

6.

Usually we use [NSNumber numberWithBool:NO] to represent a boxed true/false value, instead of a string @"NO". NSNumber is also used a lot whenever a primitive number (int, float, etc.) cannot be used (e.g. to be stored in an NSArray). I don't know if your API explicitly requires a string NO, so it may not unsuitable for you.

KennyTM
WOW! This is great stuff Kenny. I now have a lot more studying to do on these topics. Thanks for sending me in different directions ;-)
Terry Owen
By the way Kenny. I donated $5 to your Google Code project at http://code.google.com/p/networkpx/Thanks again ;-)
Terry Owen
Terry, I would seriously look at http://ericasadun.com/ and read the iPhone Cookbook. It got me up and going inside of 2 weeks. I was a perl programmer and Erica's book familiarized me enough with the essentials and some neat tricks. ps: Good question, tho.
Jann