hello wise ones...
so I spent the last week reading about NSURL, NSData, NSFileHandle, and sandboxing. I have some code here that works... I'd like to share it with you to see if I am indeed following best practices, and if anyone has any suggestions as to how to improve upon it, I welcome all constructive criticism.
this app is just a test app to see if I can read from one file a user selects, and write it to a file the app creates in the destination of the user's choosing. I have three buttons and a textField... the buttons are "select file", "select folder" (destination), and "run." The textField allows the user to input the desired name of the file. I have in XCode set the sandbox capabilities to be able to read/write for user selected files.
@interface RootViewController : NSViewController
{
NSURL *readFileURL;
NSURL *writeFileFolderURL;
}
@implementation RootViewController
- (IBAction)selectFileButton:(NSButton *)sender
{
NSOpenPanel *selectFile = [NSOpenPanel openPanel];
[selectFile setCanChooseFiles:true];
[selectFile setCanChooseDirectories:true];
[selectFile setAllowsMultipleSelection:false];
[selectFile setPrompt:@"Select"];
[selectFile setMessage:@"Select video file..."];
[selectFile runModal];
readFileURL = [selectFile.URLs firstObject];
}
- (IBAction)selectFolderButton:(NSButton *)sender
{
NSOpenPanel *selectFolder = [NSOpenPanel openPanel];
[selectFolder setCanChooseFiles:false];
[selectFolder setCanChooseDirectories:true];
[selectFolder setAllowsMultipleSelection:false];
[selectFolder setPrompt:@"Select"];
[selectFolder setMessage:@"Select destination folder..."];
[selectFolder runModal];
writeFileFolderURL = [selectFolder.URLs firstObject];
}
- (IBAction)runButton:(NSButton *)sender
{
NSError *readFileError = nil;
NSFileHandle *readFileHandle;
readFileHandle = [NSFileHandle fileHandleForReadingFromURL:readFileURL error:&readFileError];
if (readFileError) {
NSLog(@"Fail: %@", [readFileError localizedDescription]);
return;
}
NSData *readDataLoad = [NSData new];
NSMutableData *readDataBuffer = [NSMutableData new];
readDataLoad = [readFileHandle readDataOfLength:50]; //get first 50 (50 is just a random number for testing purposes)
[readDataBuffer appendData:readDataLoad];
readDataLoad = [readFileHandle readDataOfLength:50]; //get next 50
[readDataBuffer appendData:readDataLoad];
NSString *writeFileTempName = [_writeFileNameTextField stringValue]; //get user's desired name
NSString *writeFileName = [writeFileTempName stringByAppendingString:@".mid"]; //append .mid
NSURL *destinationURL = [writeFileFolderURL URLByAppendingPathComponent:writeFileName]; //append file name to URL
NSError *writeError = nil; //create error pointer
BOOL success = [readDataBuffer writeToURL:destinationURL options:0 error:&writeError]; //write to file
if(!success){
NSLog(@"Fail: %@", [writeError localizedDescription]);
}
[readFileHandle closeFile];
}
some questions:
1. I'm assuming that by setting my sandbox settings in XCode that the same settings will apply to my stand alone app, yes?
2. The way I am using readDataOfLength (which is a NSData object) and then handing it off to my readDataBuffer (which is an NSMutableData object) seems clunky. Is there a better way? The idea here is to slowly amass the data I need in the readDataBuffer, and then only have to writeToURL once at the end.
3. I'm using two different error pointers... does that matter, or should I just be using one pointer and be done with it?
Thanks as always for your help and guidance.