Objective-Cで非同期ファイルコピー

NSFileManagerでファイルをコピーできるのだけど、非同期で送ることができないので、その間GUIがかたまってしまう。 それはよろしくない。基本的にファイルIOは非同期でやりたい。 ということで非同期のファイルコピーを実装する。

FSCopyObjectAsyncというメソッドを利用すればよい。 以下のような感じになる。

- (void) copyFile: (NSString*) destinationFilePath{
	CFRunLoopRef runLoop = CFRunLoopGetCurrent();
	FSFileOperationRef fileOp = FSFileOperationCreate(kCFAllocatorDefault);
	
	OSStatus status = FSFileOperationScheduleWithRunLoop(fileOp, runLoop, kCFRunLoopDefaultMode);
	if( status )
    {
		return;
    }
	
	FSRef source;
	FSRef destination;
	
	FSPathMakeRef((const UInt8 *)[filePath fileSystemRepresentation], &source, NULL );
	Boolean isDir = true;
	FSPathMakeRef( (const UInt8 *)[destinationFilePath fileSystemRepresentation], &destination, &isDir );    
    
    FSFileOperationClientContext clientContext = {0}; // このオブジェクトに入れたオブジェクトがCallbackで受け取れる
    clientContext.info = self;
    
	status = FSCopyObjectAsync (fileOp,
                                &source,
                                &destination,
                                NULL,
                                kFSFileOperationDefaultOptions,
                                statusCallback,
                                1.0,
                                &clientContext);
	CFRelease(fileOp);
	if( status )
    {
    }
}

// ある程度小分けにしてコピーされる。
// ひとかたまりコピーするごとにこの関数が呼び出される
static void statusCallback (FSFileOperationRef fileOp,
                            const FSRef *currentItem,
                            FSFileOperationStage stage,
                            OSStatus error,
                            CFDictionaryRef statusDictionary,
                            void *info){
}

サンプルプロジェクト 補足

Written on April 18, 2011