tl;dr: Can't load JSON file received via DropInteraction in iOS app running in Mac Catalyst.
I am currently refactoring my existing (Swift) iOS codebase to run on macOS under Mac Catalyst but am having trouble with reading, loading or even seeing JSON files that are received by my UIDropInteractionDelegate
.
I am following the example here: https://appventure.me/guides/catalyst/how/drag_and_drop.html
I am trying to drop a file snse.json
, which is a regular pretty-printed JSON text file, but in func 3 (performDrop
), session.items
is a single item array with nothing useful in it.
When I throw a breakpoint in performDrop
, I get the following debug output:
(lldb) po session.items.first?.itemProvider
▿ Optional<NSItemProvider>
- some : <NSItemProvider: 0x600003876ca0> {types = (
"public.json",
"com.apple.finder.node"
)}
(lldb) po session.items.first?.itemProvider.suggestedName
▿ Optional<String>
- some : "snse.json"
(lldb) po session.items.first?.localObject
nil
(lldb) po session.items.first?.previewProvider
nil
(lldb) po session.items.first?.itemProvider.canLoadObject(ofClass: URL.self)
▿ Optional<Bool>
- some : false
(lldb) po session.items.first?.itemProvider.canLoadObject(ofClass: String.self)
▿ Optional<Bool>
- some : false
This is the code I have so far:
class SentimentViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.interactions.append(UIDropInteraction(delegate: self))
}
}
extension SentimentViewController: UIDropInteractionDelegate {
static let JSONTypeIdentifier = "public.json"
// 1
func dropInteraction(_ interaction: UIDropInteraction,
canHandle session: UIDropSession) -> Bool {
return session.hasItemsConforming(toTypeIdentifiers: [JSONTypeIdentifier])
}
// 2
func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
return UIDropProposal(operation: .copy)
}
// 3
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
// This is called with an array of NSURL
let _ = session.loadObjects(ofClass: URL.self) { urls in
for url in urls {
self.importJSONData(from: url)
print(url)
}
}
}
private func importJSONData(from url: URL) {
print("I would love to load data from \(url).")
}
}
I'm sure I'm doing something wrong, but I just can't tell what. Do I need to request permissions to read local files? Is there a step I missed? Any help is greatly appreciated!
You don't need URL, because drop item already has item provider for JSON data, so it is just needed to extract that data from
NSItemProvider
and decode.Here is fixed parts (tested with Xcode 12.1)