HanXu
HanXu

Reputation: 5597

Why my program can run in Xcode, but cannot running as a separate app?

My program loads some data from a file and then draws them.

The file-reading part is like this:

- (void)load_file
{
    NSFileHandle *inFile = [NSFileHandle fileHandleForReadingAtPath:@"map_data"];
    NSData  *myData=[inFile readDataToEndOfFile];
    NSString *myText=[[NSString alloc]initWithData:myData encoding:NSASCIIStringEncoding];
    NSArray *values = [myText componentsSeparatedByString:@"\n"];
    for (NSString *string in values) {
        NSArray *lines=[string componentsSeparatedByString:@" "];
        if ([lines count] != 2) break;
        NSPoint point= NSMakePoint([lines[0] floatValue], [lines[1] floatValue]);
        [points addObject:[NSValue valueWithPoint:point]];
    }
    [self setNeedsDisplay:YES];
}

When debugging, I put the data file in the directory of [NSBundle mainBundle], and the program works fine.

However, when I use achieve to take the app out, it never runs. I put the data file in the same path with the app, but it seems fail to load it.


Update

I tried to use c++, but still fails.

- (void)load_file
{
    ifstream inf("map_data");
    double x, y;
    while (inf >> x >> y) [points addObject:[NSValue valueWithPoint:NSMakePoint(x, y)]];
    inf.close();
}

I tried to change the build scheme to release and run, which is fine. But whenever I go directly into the finder of app and double click it, it does not work and seems nothing is loaded.

Upvotes: 0

Views: 98

Answers (2)

bbum
bbum

Reputation: 162712

  • add the file to the project as a Resource (this will cause it to be copied into the app wrapper in the right spot)

  • use `[[NSBundle mainBundle] pathForResource:@"map_data" ofType:nil];

That should give you the path to the file. The file should not be manually copied, it should not be next to the app wrapper, nor should you [conjecture] ever try changing or replacing the file once it is in your app wrapper.

The reason why it seems to work sometimes is mere coincidence. You are passing a partial path to NSFileHandle and it happens that the current working directory of your app sometimes points to the right spot such that the data file is available.

Upvotes: 2

DrummerB
DrummerB

Reputation: 40211

I'm not sure how relative paths are handled by NSFileHandle, but usually you set up paths using the NSBundle class.

NSString *path = [[NSBundle mainBundle] pathForResource:@"myfile" ofType:@"ext"];

You can also simply initialize an NSString from the contents of a file, you don't need to first read it into an NSData using NSFileHandle.

NSString *text = [[NSString alloc] initWithContentsOfFile:path 
                                   encoding:NSASCIIStringEncoding error:nil];

(Use the error parameter, if you want proper error handling)

Upvotes: 1

Related Questions