2

I have a loop set to copy files to a directory, however, when a file already exists at the destination, a UIAlertView displays prompting the user to overwrite, skip, cancel, etc. My question is, how can I pause the loop until the UIAlertView is dismissed, at which point the next (if any) UIAlertView will be displayed.

The loop code looks like this:

for (NSString *fileInArray in selectedFiles) {
    [self copyFile:fileInArray destination:[self.path stringByAppendingPathComponent:[fileInArray lastPathComponent]]];
}

The paths are stored in an NSArray as NSStrings, the NSArray is created in another method (copy/move) this is the paste method.

This is the method to paste files (for the copy function).

- (void) copyFile:(NSString *)input destination:(NSString *) output{



    NSFileManager *copyManager = [NSFileManager defaultManager];
    NSError *error;
    if ([copyManager fileExistsAtPath:output]){

            RIButtonItem *overwriteItem = [RIButtonItem itemWithLabel:@"Overwrite" action:^{
                NSError *removeError;
                [copyManager removeItemAtPath:output error:&removeError];
                if (removeError){
                    [self displayError:[NSString stringWithFormat:@"There was a problem overwriting the file '%@'. %@", [output lastPathComponent], [removeError localizedDescription]]];
                }
            }];
            RIButtonItem *cancelItem = [RIButtonItem itemWithLabel:@"Skip" action:^{

            }];

            RIButtonItem *renameItem = [RIButtonItem itemWithLabel:@"Rename" action:^{
            }];
            UIAlertView *fileExistsAlert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"A file already exists at the destination matching this file." cancelButtonItem:cancelItem otherButtonItems:overwriteItem, renameItem, nil];
            [fileExistsAlert show];
    }
    [copyManager copyItemAtPath:input toPath:output error:&error];
    if (error){
        [self displayError:[error localizedDescription]];
    }

Currently, the first UIAlertView displays for about 1 second and then is hidden, at which point the interface becomes grey, as if it's disabled and no more UIAlertViews appear. Using the latest iOS SDK.

Terry
  • 616
  • 6
  • 16
  • You should change your approach to an "asynchronous" pattern. This can for instance be done by using a global index for `selectedFiles`. If the file exists you break the loop and show the alert dialog. Then you continue the loop with the last index. – Hyndrix Jan 02 '14 at 16:00
  • Would you have any pointers or examples to look at. I'm not sure I understand what you mean by "breaking the loop and then continuing with the last index". Unless, of course, you're proposing that I alter my "copyFile" method to allow the NSArray as an input. Therefore upon detecting a duplicate file I could break the loop, assign the current index to a global variable, handle the duplicate and then (somehow) continue the loop from the one method. I'm just looking for the most efficient/safe way to do this. – Terry Jan 02 '14 at 16:05
  • change `- (void) copyFile:(NSString *)input destination:(NSString *) output` to `- (void) copyFile:(NSString *)input destination:(NSString *) output atIndex:(NSInteger)index` and save the current index globally to be used after the user selection in the UIAlertView's delegate. – Chris Jan 02 '14 at 17:30
  • @Chris that sounds good, however, the loop does not pause but continues to run, which will continue to create multiple UIAlertViews before the initial one has been dismissed. If I were to check if a duplicate file already exists in the loop, how would I continue the loop after breaking to handle the UIAlertView? – Terry Jan 02 '14 at 19:46

3 Answers3

0

For the pattern you could do something like this. Instead of the base loop you could pass in the next index to copy into your copy function. Then the copy function would call itself with something like performSelector afterDelay with the next index. If the alert were to show it would not call itself and the next call would be made when the alert was dismissed.

0xFADE
  • 832
  • 5
  • 7
0

the clue is to advance the runloop. but while this works fine, use async access getting rid of the loop.

for an example see: Make iOS blocks execute synchronously

Community
  • 1
  • 1
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
0

When presented with a similar problem,I decided to create a function that checks to see which errors were occurring, compile the errors into an array, and display the errors using one UIALERTVIEW. You can create a function that adds to an array that contains the files/filenames that had issues, then display a single UIALERT VIEW stating which files failed to upload/or were duplicates. If you have a lot of text to display in the UIALERTVIEW, then the UIALERTVIEW becomes scrollable when its presented with more text than it can place in the UIALERTVIEW.

ConfusedDeer
  • 3,335
  • 8
  • 44
  • 72