NSFileManager: continue burning to disk in background?

in my iPhone application, I use the default NSFileManager to copy and move some data. The amount of data may be a little MB, so it may take several seconds to complete the copy. If now the user starts the copying process and leaves the application, can I continue to burn to disk in the background? If so, how? I do not want to start a new copy process, but I only finish it.

I currently use two types of method calls:

[imageData writeToFile:path atomically:YES]; 

and

 [fm copyItemAtPath:sourcePath toPath:destinationPath error:&error]; 

Both calls are wrapped in a different method and are executed in the background using -performSelectorInBackground:withObject:

Another question: can I get any information about how the write operation has progressed, or at least if it has already completed?

EDIT: More info: Currently, I have not performed any background tasks at all. What happens when performing disk operations when a user clicks the home button? They are simply disabled, but the file is incomplete? Can I continue recording the next time I start? Are they canceled and the incomplete file is deleted?

To summarize: I am writing data to disk, and I want it to remain constant when the user presses the Home button during a write operation. How do I achieve this?

+4
source share
2 answers

By default, the application does not end when the user clicks the home button. Therefore, he must finish this task, since it does not last too long. If this takes a long time, please take a look at this question: How to implement task completion

One thing: I think you're confused by what the function SelectorInBackground: withObject: really does. The background used in "... I continue to burn to disk in background mode", and the background in "performSelectorIn Background : withObject:" does not match the background

Previous background: This is when the application becomes invisible to the user, but still works, at least for a while. (When the user presses the home button twice and switches to another application)

Last Background: Refers to a background thread that is opposite to the main thread.

In this case, if you use or do not execute SelectorInBackground: withObject: this will not affect whether the application can do the background mode or not. These are completely different things.

You can set BOOL finished = YES immediately after [fm copyItemAtPath: ToPath: error:]; and save it to NSUserDefaults and check this flag when your application reappears in the foreground;)

Hope this helps;)

+4
source

You can see the NSOperationQueue documentation page here .

There are also two existing stack overflow questions that are addressed using NSOperationQueue , which are here and here , Both have accepted the answers.

As for figuring out if the file was finished writing, I had this problem when I was writing an OS X application that created a very large file. I wanted the user to be able to track the progress of the recording. I ended up using NSTimer with UIProgressBar

Essentially, you will need to determine the (expected) total file size. Then, when you write the file, you should have another method (in the checkFileWritingProgress code checkFileWritingProgress ) that you can call at periodic intervals with NSTimer . Check the current progress against the total expected file size and update the UIProgressBar .

I have provided some code to get you started.

 - (void)checkFileWritingProgress:(NSTimer *)someTimer { fileAttributes = [fileManager attributesOfItemAtPath:[NSString stringWithFormat:@"%@.data",saveLocation] error:nil]; currentFileSize = [fileAttributes fileSize]; // instance variable if(currentFileSize < maxFileSize) { // maxFileSize is instance variable [progressBar setDoubleValue:(((double)currentFileSize/(double)maxFileSize)*100)]; // progressWindows OS X only... not on iOS //[progressWindow setTitle:[NSString stringWithFormat:@"Writing... | %.0f%%",(((double)currentFileSize/(double)maxFileSize)*100)]]; } else { [progressBar setDoubleValue:100.0]; } } 

And the timer ...

 NSTimer *timer = [[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(checkFileWritingProgress:) userInfo:nil repeats:YES] retain]; //(linked to timer... this is the // CORRECT way to use a determinate progress bar) [progressBar setIndeterminate:NO]; [progressBar setDoubleValue:0.0]; [progressBar displayIfNeeded]; 

Hope this code helps. Let me know if something needs to be clarified.

+4
source

Source: https://habr.com/ru/post/1334041/


All Articles