iOS 11 Drag and Drop UIDocument

822 views Asked by At

Everything is clear about Drag and Drop except how to handle UIDocuments.

this is my (not working) implementation...

For Drag:

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {

    let doc = DataManager.shared.storage[indexPath.row] // the UIDocument to drag
    let itemProv = NSItemProvider()
    itemProv.registerFileRepresentation(forTypeIdentifier: "com.mybundle.myapp.myextension",
                                        fileOptions: [.openInPlace],
                                        visibility: .all) { completionHandler in

        completionHandler(doc.fileURL, true, nil)
        return nil
    }

    // DragItem
    let item = UIDragItem(itemProvider: itemProv)

    return [item]
}

For drop:

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {

    for item in coordinator.session.items {
        item.itemProvider.loadFileRepresentation(forTypeIdentifier: "com.mybundle.myapp.myextension", completionHandler: { (url, error) in

            if let docUrlOk = url {
                debugPrint(urlOk.absoluteString)
                DataManager.shared.load(docUrlOk)
            }
        })
    }
}

And the update method:

func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {

    if tableView.hasActiveDrag {
        if session.items.count > 1 {
            return UITableViewDropProposal(operation: .cancel)
        } else {
            return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
        }
    } else {
        return UITableViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
    }
}

Thank you so much

2

There are 2 answers

1
Enlil On BEST ANSWER

After a lot of talk with an Apple engineer I found a "semi" solution. The posted code in the question is correct, but to drag a proprietary file from your App to the Files App you have to insert the following values in the Target -> Info -> Exported UTIs field enter image description here

BUT if you drag your proprietary file from Files App back to your App there is a bug in UIKit that prevents it from working properly... the engineer told me to wait for iOS 11.3 or iOS 12, we'll see

3
Kingandyoga On

If you run the code in iPhone, you need set the dragItem.enable = YES.