0

We are presenting a UIDocumentPickerViewController with the URL to the URLForUbiquityContainerIdentifier and for whatever reason, it does not show the cancel button for all our users. Sometimes, it is completely missing and a user cannot dismiss without going to the "Recent" tab where it will force the cancel button to appear.

Here is how we present the modal:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        [self rootDirectoryForICloudWithFolderName:@"Test" createFolder:YES completion:^(NSURL *ubiquityURL) {
            
            self.picker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeJPEG] inMode:UIDocumentPickerModeOpen];
            self.picker.directoryURL = ubiquityURL;
            self.picker.delegate = self;
            
            [self presentViewController:self.picker animated:YES completion:nil];
            
        }];
        
    });
    
}

- (void)rootDirectoryForICloudWithFolderName:(NSString *)folderName createFolder:(BOOL)createFolder completion:(void (^)(NSURL *))completionHandler {
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@", folderName]];
        if (rootDirectory) {
            if (![[NSFileManager defaultManager] fileExistsAtPath:rootDirectory.path isDirectory:nil] && createFolder) {
                [[NSFileManager defaultManager] createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil];
            }
        }
        
        dispatch_async(dispatch_get_main_queue(), ^{
            completionHandler(rootDirectory);
        });
    });
}

I am setting the directoryURL to the ubiquity URL for the iCloud documents folder for our app. The strange thing is, this only happens on a new install with a unique bundle identifier. If I switch tabs, to make the cancel button appear, then on the next launch it will work correctly. But, changing the bundle identifier will cause the bug to happen again.

Apple has said this is a bug, but it still remains unfixed in iOS 14 beta 5. Can anyone think of a workaround for this issue as we would love to use this feature!

Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • Really just a guess - why not, in your app delegate, ensure the iCloud / root directory exists? The way you describe it sounds as if the presence of the relevant dir, which changes with app identifier, maybe causes it. – skaak Aug 21 '20 at 18:05
  • @skaak No, the URL is something like `file:///private/var/mobile/Library/Mobile%20Documents/iCloud~PickerError/Documents/Test/` and is based on the iCloud Container ID, not the app bundle ID. So, that URL stays the same even if I change the bundle ID. – Nic Hubbard Aug 21 '20 at 19:01
  • Ok - I was hoping that just maybe if the ```file:///private/var/mobile/Library/Mobile%20Documents/iCloud~PickerError/Documents/``` existed before hand it might solve it but that is a bit of a long shot. Forgive me for just guessing, but maybe don't create the dir in the background since it is not an expensive op and see what happens. – skaak Aug 21 '20 at 19:06
  • Just tried to create the dir on the main thread and that didn't help. Sadly. – Nic Hubbard Aug 21 '20 at 20:52
  • Hi Nic - I have the same problem toying with some Swift code in iOS 14 ... I could fix it by editing Info.plist and adding my file type to the list of exported types. – skaak Aug 28 '20 at 11:59
  • @skaak Can you post what you used as an answer? – Nic Hubbard Aug 28 '20 at 21:49
  • apologies, I think I commented too fast. I was really just experimenting with some document stuff in the latest Xcode beta 6 and at some stage the little + disappeared. I could get it back by adding my file type to the exported types *and also* by configuring the ```extension UTType``` correctly and too quickly assumed this solves your problem as well. Yous is of course the cancel button - I'd love to experiment with that a bit as well to see if it solves your issue but at present simply don't have the time ... but maybe later ... – skaak Aug 31 '20 at 12:17
  • If this helps at all, in the Xcode generated document app, there is this piece of code ```extension UTType { static var myData : UTType { UTType (importedAs : "com.blahblahblah") } }``` that I had to fix along with setting the exported type in Info.plist to get the + back. – skaak Aug 31 '20 at 12:34

0 Answers0