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 ;-)

1
  • Maybe... What are you trying to accomplish? (e.g. what part are you checking for correctness?) Commented Apr 11, 2010 at 14:35

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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 ;-)
By the way Kenny. I donated $5 to your Google Code project at code.google.com/p/networkpx Thanks again ;-)
Terry, I would seriously look at 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.