I’ve released a Cocoapod that encapsulates UIKit document picker UI; allowing the user to select iCloud documents (and Google Drive, One Drive, etc), with a simple Future based API.

The component implements both UIDocumentMenuDelegate and UIDocumentPickerDelegate and provides a simple Future based API.

Usage

NADocumentPicker.show(..) returns a Future . Hooking into onSuccess provides the URL of the file choosen by the user:

@IBAction func pickerButtonPressed(sender: UIButton) {
    let urlPickedfuture = NADocumentPicker.show(from: sender, parentViewController: self)

    urlPickedfuture.onSuccess { url in
        print("URL: \(url)")
    }
}

Implementation details.

One of the challenges of keeping a simple API, was how to ensure that the NADocumentPicker object remains in memory until the Future completes. The trick I used was to add a reference count to the object that is only freed when onComplete fires:

public class NADocumentPicker : NSObject {
    private var keepInMemory: NADocumentPicker?
    .
    .
    private func keepOurselvesInMemory() {
        keepInMemory = self
    }

    private func freeOurselvesFromMemory() {
        keepInMemory = nil
    }

    private func keepInMemoryUntilComplete() {
        keepOurselvesInMemory()
        self.promise.future.onComplete { [unowned self] _ in
            self.freeOurselvesFromMemory()
        }
    }

    private init(...) {
      .
      .
      keepInMemoryUntilComplete()
    }
}

If the property keepInMemory is non-nil the object will not be freed. The object sets keepInMemory to nil within an onComplete block. This completion block will be called for success or failure. Success when the user picked a file and failure if the user dismisses the UI without choosing a file.

Installation

NADocumentPicker is available as a Cocoapod. To incorporate the document picker into your project add the following to your Podfile eg:

target '<YourProject>' do
    pod 'NADocumentPicker'
    .
    .
end

You can try-out NADocumentPicker demo project by using the cocoapod try option as:

$ pod try NADocumentPicker

See Also