0

I'm trying to create a Mac OS X app where there are some default sound and the user can add others if he wants. I'm loading the sounds to an array in -awakeFromNib :

for (NSString *str in [PreferencesController beats]) {
    resourcePath = [[NSBundle mainBundle] pathForSoundResource:str];
    beat = [[NSSound alloc] initWithContentsOfFile:resourcePath byReference:YES];
    [beat setLoops:YES];
    [beat setName:str];
    [beatsArray addObject:beat];
}

Everything works fine until the app tries to add to the array a sound added by the user. It says : *** -[NSURL initFileURLWithPath:]: nil string parameter. I'm guessing that it can't find the URL of the file but I'm copying the file to the app's directory when the user selects it by the following code :

if ( [openDlg runModalForTypes:[NSArray arrayWithObjects:@"aif",@"aiff",@"mp3",@"wav",@"m4a",nil]] == NSOKButton)
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;

    NSString *dataPath = [[NSBundle mainBundle] bundlePath];
    NSLog(@"Datapath is %@", dataPath);
    NSLog(@"Selected Files : %@",[[openDlg URLs] objectAtIndex:0]);

    [fileManager copyItemAtURL: [[openDlg URLs] objectAtIndex:0] toURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]] error:&error];
        NSLog(@"File copied");
    NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:[PreferencesController beats]];
    NSString *fileName = [[[openDlg URL] path] lastPathComponent];
    NSArray *fileNameArray = [fileName componentsSeparatedByString:@"."];
    [newArray addObject:[fileNameArray objectAtIndex:0]];
    NSLog(@"%@",newArray);
    [PreferencesController setBeats:newArray];
    [self awakeFromNib];
    [_tableView reloadData];
}

What's wrong with this code?

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75

1 Answers1

-1

Looks like you're trying to copy a file to a folder because you're just using the bundle path as the destination URL. The destination URL needs to specify the full path including the destination file name.

Try logging the error when the file is copied:

NSLog(@"File copied with error: %@", error);

This line contains the error:

[fileManager copyItemAtURL: [[openDlg URLs] objectAtIndex:0] toURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]] error:&error];

Specifically, the problem is that the destination URL is a folder:

[[NSBundle mainBundle] bundlePath]

It should be something like:

[[[NSBundle mainBundle] bundlePath] stringByAppendingString:[[[[openDlg URLs] objectAtIndex:0] path] lastPathComponent];

Then, once you have it working, as @Abizern says in the comments, saving to the bundle is a bad idea (it's part of the app). Once you have it working, you should choose a better location to save the sounds to (like a support document folder for the app, Programmatically get path to Application Support folder)

Community
  • 1
  • 1
Wain
  • 118,658
  • 15
  • 128
  • 151
  • It says : `Error Domain=NSCocoaErrorDomain Code=516 "“1 Audio Track” couldn’t be copied to “Debug” because an item with the same name already exists."` But if the file exists, it should be able to load the sound in the array no? – user2331955 May 03 '13 at 12:12
  • Not if the item that already exists if a folder. Try also logging the path that you're trying to load to play the sound and see if there is actually a sound file there. – Wain May 03 '13 at 12:14
  • Ok, ignore the logging, just fix the path you're saving the file to. – Wain May 03 '13 at 12:18
  • I don't get what you mean by _fix the path you're saving the file to_ – user2331955 May 03 '13 at 12:23
  • 4
    Writing to the application bundle is a bad idea. – Abizern May 03 '13 at 12:40
  • It says that the destination URL is nil. – user2331955 May 03 '13 at 12:47
  • @Abizern And why a bad idea? I'll be sure that the content will be there and it's an easy directory to use in the code... – user2331955 May 03 '13 at 12:48
  • 2
    @user2331955 the user doesn't necessarily have permission to write to the app bundle. If they do, they writing into it might break your app, change its behaviour, or break its code signing identity. –  May 03 '13 at 13:37