As most of the apps, the one I'm currently working on calls to a web service on a regular basis.

The big issue here is that these calls are made to URLs that, while are part of the same API, do not have any structure nor are versioned.

For instance, the authentication URL looks something like http://host.com/u/login, but the URL that lets me download resources from the server to display on the app looks like http://host.com/mobile/v2/resource. Within the same app, I often have to call http://host.com/api/v3/resource too1.

So, you see, these URLs are a mess. Some are prefixed with /api/, others aren't. Some have version numbers on them, some others don't.

On top of that, the app should be able to point to different hosts on the fly. The login endpoint could be http://host.com/u/login, http://host2.com/u/login or http://host3.com/u/login, and so forth for each of the APIs I have to call2.

What would be the best way to handle this situation?

URLManager

Here's what I'm doing:

// URLManager.h
#import <Foundation/Foundation.h>

@interface URLManager : NSObject
+ (NSURL *)loginURL;
+ (NSURL *)resourceURL;
// The rest of the URLs representing different API endpoints.
@end

The implementation looks like (something along the lines of) this:

// URLManager.m
@implementation URLManager
+ (NSURL *)baseURLWithPath:(NSString *)path {
    NSString *baseString = nil;
    ServerCode serverCode = ... // ServerCode is an NS_ENUM

    switch (serverCode) {
        case ServerCodeFirst: {
            baseURL = @"http://host.com/";
        }
            break;

        / ** ** /
    }

    if (path) {
        baseString = [baseString stringByAppendingString:path];
    }

    return [NSURL URLWithString:baseString];
}

+ (NSURL *)loginURL {
    return [self baseURLWithPath:@"/u/login"];
}

+ (NSURL *)resourceURL {
    return [self baseURLWithPath:@"/api/v3/resource"];
}
@end

So, whenever I need to hit the resource API endpoint, I can get the URL easily:

// This would tipically happen on a class whose only purpose is to make API calls.
NSURL *resourceURL = [URLManager resourceURL]; // => http://host.com/api/v2/resource  

Since the API is not versioned (at least on a realiable or sensitive way), there's no point on creating constants for the version numbers. Once the server side is normalised, that would be a much welcomed change here.