How do I load a TMX Map from my Documents Directory?

I'm downloading the TMX map and the Tileset from my server, and saving them into the iOS apps documents directory:

- (void)downloadMap:(void (^)(NSURL *filePath))callback;
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    NSURL *URL = [NSURL URLWithString:@"http://localhost:9950/download"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        NSURL *documentsDirectoryPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
        return [documentsDirectoryPath URLByAppendingPathComponent:[response suggestedFilename]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        DLog(@"Saved: %@", filePath);
        [self downloadTileMap:^(NSURL *filePath) {
            if (callback) {
    [downloadTask resume];

This downloads both assets. I then try to load my Map:

[self downloadMap:^(NSURL *filePath) { = [CCTMXTiledMap tiledMapWithTMXFile:[filePath absoluteString]];

And Cocos2D refuses to load it. It doesn't find the files, even though the logs state:

Saved: file:///Users/ethan/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2FDEA5E2-052D-4E7B-B7DD-3FA29B5BD4D0/Documents/test_map.tmx
Saved: file:///Users/ethan/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2FDEA5E2-052D-4E7B-B7DD-3FA29B5BD4D0/Documents/tmw_desert_spacing.png
-[CCFileUtils fullPathForFilename:resolutionType:] : cocos2d: Warning: File not found: file:///Users/ethan/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2FDEA5E2-052D-4E7B-B7DD-3FA29B5BD4D0/Documents/tmw_desert_spacing.png

And if I enumerate over all files in the Documents directory, I get:

Files: (

I've convinced myself that the files are there. The TMX map loads the tileset as a relative path:

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="16" height="40" tilewidth="32" tileheight="32">
 <tileset firstgid="1" name="tmw_desert_spacing" tilewidth="32" tileheight="32" spacing="1" margin="1">
  <image source="tmw_desert_spacing.png" width="265" height="199"/>
 <layer name="Walkable" width="16" height="40">
  <data encoding="base64" compression="gzip">
 <layer name="Collidable" width="16" height="40">
  <data encoding="base64" compression="gzip">

If this were loading from the Bundle, it would be fine. Why doesn't it work from the Documents directory?


I'm going to file this one away as a bug in cocos2d (or a feature request). Upon trying to load a file, it will attempt to only load it from the bundle. It simple won't load it from the Documents Directory.

So I fixed it!

In CCFileUtils.m:

- (NSString *)applicationDocumentsDirectory;
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

This is a convenience method to get the iOS application's directory.

I then change pathForResource:ofType:inDirectory: to be:

-(NSString*) pathForResource:(NSString*)resource ofType:(NSString *)ext inDirectory:(NSString *)subpath
    // An absolute path could be used if the searchPath contains absolute paths
    if( [subpath isAbsolutePath] ) {
        NSString *fullpath = [subpath stringByAppendingPathComponent:resource];
        if( ext )
            fullpath = [fullpath stringByAppendingPathExtension:ext];

        if( [_fileManager fileExistsAtPath:fullpath] )
            return fullpath;
        return nil;

    if (resource) {
        NSString *fullPath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:resource];
        if( ext )
            fullPath = [fullPath stringByAppendingPathExtension:ext];

        if ([_fileManager fileExistsAtPath:fullPath]) {
            return fullPath;

    // Default to normal resource directory
    return [_bundle pathForResource:resource

Basically, before defaulting into the Bundle directory, check if the resource exists in the Documents Directory. If it does, return it!

Now my map loads without a problem.

Need Your Help

How to change the root of a clientspec using cmd

client set perforce root

I have created a new clientspec using the command :

Are GIT refs always case insensitive?


I was testing on my local machine (OS-X 10.10) which uses a case insensitive file system (HFS+ [CI]) - when I reset to the head: