onDrop #1212
-
Hi! I'm trying to implement dropping files into my macOS app using TCA. .onDrop(
of: ["public.file-url"],
isTargeted: $dragOver,
perform: { providers in
providers.first?.loadDataRepresentation(
forTypeIdentifier: "public.file-url",
completionHandler: { (data, error) in
if let data, let path = NSString(data: data, encoding: 4), let url = URL(string: path as String) {
let image = NSImage(contentsOf: url)
DispatchQueue.main.async {
self.image = image
}
}
}
)
return true
}
) The |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
For anyone interested! Got it working by making the following environment client: public struct OnDropImageClient {
public struct OnDropError: Error, Equatable { }
var onDrop: ([NSItemProvider]) -> Effect<NSImage, OnDropError>
public static let noop = Self(
onDrop: { _ in .none }
)
public static let live = Self(
onDrop: { providers in
Effect<NSImage, OnDropError>.future { callback in
providers.first?.loadDataRepresentation(
forTypeIdentifier: "public.file-url",
completionHandler: { (data, error) in
if
let data,
let path = NSString(data: data, encoding: 4),
let url = URL(string: path as String),
let image = NSImage(contentsOf: url)
{
callback(.success(image))
}
callback(.failure(.init()))
}
)
}
}
)
} The following modifier on my view: .onDrop(
of: ["public.file-url"],
isTargeted: viewStore.binding(
get: \.dragOver,
send: ImageInputAction.dragOverChanged
),
perform: { providers in
viewStore.send(.onDropImageStarted(providers))
return true
}
) and the following actions in my reducer: case .dragOverChanged:
state.dragOver.toggle()
return .none
case .onDropImageStarted(let providers):
return env.onDropImage.onDrop(providers)
.receive(on: env.mainQueue)
.catchToEffect()
.map(ImageInputAction.onDropImageCompleted)
case .onDropImageCompleted(.success(let image)):
return .none |
Beta Was this translation helpful? Give feedback.
For anyone interested! Got it working by making the following environment client: