There's a great Swift library out there now called SwiftReorder that is MIT licensed, so you can use it as a first party solution. The basis of this library is that it uses a UITableView extension to inject a controller object into any table view that conforms to the TableViewReorderDelegate:
extension UITableView {
    private struct AssociatedKeys {
        static var reorderController: UInt8 = 0
    }
    /// An object that manages drag-and-drop reordering of table view cells.
    public var reorder: ReorderController {
        if let controller = objc_getAssociatedObject(self, &AssociatedKeys.reorderController) as? ReorderController {
            return controller
        } else {
            let controller = ReorderController(tableView: self)
            objc_setAssociatedObject(self, &AssociatedKeys.reorderController, controller, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            return controller
        }
    }
}
And then the delegate looks somewhat like this: 
public protocol TableViewReorderDelegate: class {
    // A series of delegate methods like this are defined:
    func tableView(_ tableView: UITableView, reorderRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
}
And the controller looks like this:
public class ReorderController: NSObject {
    /// The delegate of the reorder controller.
    public weak var delegate: TableViewReorderDelegate?
    // ... Other code here, can be found in the open source project
}
The key to the implementation is that there is a "spacer cell" that is inserted into the table view as the snapshot cell is presented at the touch point, so you need to handle the spacer cell in your cellForRow:atIndexPath: call:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let spacer = tableView.reorder.spacerCell(for: indexPath) {
        return spacer
    }
    // otherwise build and return your regular cells
}