I want to share a Transferable (JSON-encoded) data struct from some HostApp with an Extension of my ContainingApp, and get a different Transferable (also JSON-encoded) data struct back on success.
Since I want to present my ContainingApp's AppIcon in the sharing sheet to make it easy for the user to find it, I started building a Sharing Extension and not an Action Extension.
AFAIK the difference is only in the presentation (Sharing Extension: Icon+name of the ContainingApp vs Action Extension: simple b/w system icon plus a string describing the action (e.g. "Copy", "Save to Files")), and the data flow is identical. Please correct me if I'm wrong.
I added the Sharing Extension to my ContainingApp (which are both in the same app group so they can use a shared container to exchange data).
The (real) HostApp is from a different company we are collaborating with, and thus is not in our app group.
Once everything runs I will add a tailored NSExtensionActivationRule to make sure our Sharing Extension is only shown to our partner's HostApp. Currently I am still using TRUEPREDICATE.
The goal is that after the user tapped the "Continue with ContainingApp" (Share-)button in the HostApp, iOS will only show my ContainingApp icon and nothing else, since that's the only useful choice for the user.
Side Question 1: The best user experience would be if the HostApp could directly present our extension when the user tapped the "Continue with ContainingApp"-button, without the user needing to choose it manually in the Share-sheet, but I guess this is not possible for privacy/security reasons, right?
In the debugger of the HostApp I see this error:
Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead.
Library: UniformTypeIdentifiers | Subsystem: com.apple.runtime-issues | Category: Type Declaration Issues
but I definitely want to define and export both ShareInput and ShareResult as UTExportedTypeDeclarations in my extension, and all 3rd-party apps (like this demo HostApp) using my extension need to import them.
Side Question 2: Can I just ignore this error? And tell the 3rd-party app developers they also can ignore it?
After the user tapped on the ContainingApp icon in the sharing dialog, my Sharing Extension will show its dialog, presenting the shared item it got from the HostApp, and let the user edit the text.
When the user taps the "Save"-button in my extension, it creates a ShareResult struct to send back to the HostApp, and dismisses the sheet.
This (kinda) works when I share plain text with the Text button in my HostApp.
My ContainingApp icon is shown together with Mail, Messages, and other apps that can process plain text; with shortcuts to persons and devices (AirDrop targets) in the line above, and with actions (Copy, New Quick Note, Save to Files, Save to Citator, Certificat, Airdrop) below.
When I choose my ContainingApp, the extension runs and shows the text it got.
("Kinda" because I am still struggling to send data back. See below...)
So the principal operation works...
Side Question 3: In the HostApp, can I use ShareLink() to present the Share-sheet and receive the result struct or do I always need to
activityViewController!.completionWithItemsHandler = completionHandler
windowScene.keyWindow?.rootViewController?.present(activityViewController!, animated: true, completion: nil)
and process the result in the completionHandler?
If returning (any) data from the extension is possible with ShareLink() also, then how? I didn't find any sample showing this...
I implemented the ShareLink() anyway (and ignore the result part for the moment).
When I try to share a ShareInput struct with the ShareLink button, the same persons are sorted differently, there are less app icons (9 instead of 13), and less actions (only 3: New Quick Note, Save to Files, AirDrop):
Note that while the preview correctly shows the preview text provided ("shareInput"), the preview image left of it is blank (instead of arrowshape.right.fill):
let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill"))
When I choose my ContainingApp, the extension runs ...
On iOS17, I see that indeed my ShareInput data arrived in my extension:
❗️itemProvider=<NSItemProvider: 0x301b1c460> {types = (
"com.myapp.shareInput"
)}
Library: ShareExtension | Subsystem: com.myapp.containingdemo.ShareExtensionDemo | Category: ShareSheet
However, on iOS 16 it doesn't work:
Host[8615:634470] [Type Declaration Issues] Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead.
Host[8615:634462] [ShareSheet] Couldn't load file URL for Collaboration Item Provider:<NSItemProvider: 0x280f49180> {types = (
"com.myapp.shareInput"
)} : (null)
That error is shown before I choose the ContainingApp to share with.
When I do that, I get:
ShareExtension[8774:636786] [ShareSheet] ❗️itemProvider=<NSItemProvider: 0x28243a300> {types = (
"dyn.age8u",
"public.file-url"
)}
which clearly shows the ShareInput struct was not transferred to the extension.
But since I don't know how to transfer the ShareResult back to the HostApp when using a ShareLink, I cannot continue this approach anyway.
When I try to share a ShareInput struct with the JSON button (using present(activityViewController)), I see (both on iOS 16 and iOS 17):
My extension (rather, the ContainingApp's icon) is not shown as Sharing target (even though it still has TRUEPREDICATE), which means that my code didn't manage to pack the ShareInput struct for the activityViewController - and thus it doesn't know what to share.
I did the same as with the plainText item before:
let shareInput = ShareInput(inputStr: "ShareInput as JSON")
let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill"))
VStack(spacing: 25.0) {
Text("HostApp!")
ShareButton(title: "Text", shareItems: [ItemSource(dataToShare: "sharing some text")])
ShareButton(title: "JSON", shareItems: [ItemSource(dataToShare: shareInput)])
ShareLink("ShareLink", item: shareInput, preview: preview)
}
(I will continue in the next posting)
Core Transferable
RSS for tagDeclare a transfer representation for your model types to participate in system sharing and data transfer operations.
Posts under Core Transferable tag
16 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hey all, my first time posting on these forums as I've finally become completely stumped. I'm working to implement a ShareLink to share data between users on my app, and have gotten pretty far (file saves, sends correctly), but am having significant issues getting the link to open in my app when sharing by email and not getting any action at all when tapping a shared link in iMessage. I'll go through my setup below:
I have declared my new UTType, and created my new model which conforms to transferable here:
struct transferTemplate: Codable {
var id: UUID = UUID()
var name: String = "TempName"
var words: [String] = ["word1","word2"]
}
extension transferTemplate: Transferable {
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .oltemplate)
}
}
extension UTType {
static var oltemplate: UTType { UTType(exportedAs: "com.overloadapp.oltemplate") }
}
I have declared the document type in my info.plist:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Template Session</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.overloadapp.oltemplate</string>
</array>
</dict>
</array>
I have declared the Exported Type Identifier:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.json</string>
</array>
<key>UTTypeDescription</key>
<string>Template Session</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>com.overloadapp.oltemplate</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>oltemplate</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/json</string>
</array>
</dict>
</dict>
</array>
I've also included the "LSSupportsOpeningDocumentsInPlace" boolean to True in the PLIST.
My physical ShareLink setup is:
@State private var transferred: transferTemplate = transferTemplate(name: "NameTemplate", words: ["One","Two"])
...
ShareLink(item: transferred, preview: SharePreview("Share your template", image: Image("tanLogo")))
Heres where the above code gets you:
ShareLink brings up the share sheet and allows you to send the file (with the .oltemplate file extension). Sharing via iMessage will send a file, but within iMessage, the file cannot be opened at all. By email, the file can be opened but does not show any information. If you open the ShareSheet within the email attachment, you can manually choose to open the file in my app. If the file is saved to "Files", it will open my app when it is tapped (work as intended).
Heres what I have tried to fix this:
Modifying the Exported File Type "Conforms to" value. Ive used public.data, public.text, public.json.
Including and not including the mime type
I've scoured forums trying to solve this issue, and it doesn't seem like there is a clear cut solution for this issue. I appreciate any help you can provide! Please let me know if I can include any more helpful information.
I am trying to use a ShareLink to share multiple transferrable, and I cannot work out which of the initialisers to use - none seem to work.
Assuming I have a transferable that takes some data and processes it asynchronously:
struct MyTransferable: some Transferable {
let renderer: Renderer
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(exportedContentType: .png) { transferable in
let image = try await transferable.render.render()
return image
}
}
}
In SwiftUI, I want to share N of these transferables. For example:
struct MyView: View {
private var transferables: [any Transferable] {
[MyTransferable(), MyTransferable()]
}
var body: some View {
ShareLink("Renders", items: transferables)
}
}
But the compiler doesn't like this - it complains with "No exact matches in call to initializer".
Is this possible? I feel like it should be?
I am currently working on a SwiftUI project and encountering an issue with the .copyable(_:) modifier. I want to copy the currently selected items in a List, and while using .copyable(_:) works outside of navigation components, it doesn't seem to have any effect when used within NavigationSplitView or NavigationStack.
Has anyone successfully implemented copying functionality within a navigation structure using .copyable(_:)?
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationSplitView {
List(0..<10) {
Text("row \($0)")
}
} detail: {
CopyableList()
}
}
}
struct CopyableList: View {
let strings = ["Alpha", "Beta", "Gamma"]
@State private var selection: Set<String> = []
var body: some View {
List(strings, id: \.self, selection: $selection) {
Text($0)
}
.copyable(Array(selection))
}
}
Hello!
I'm working on an app that generates CSV files in memory and allows users to export them through a ShareLink. I am using a custom UTType for my CSV files as .commaSeparatedText exports a .txt file, and a custom UTType was proposed as a workaround here: https://www.hackingwithswift.com/forums/swiftui/sharelink-problem-with-csv-file/21194.
The app works on a development build, albeit with a lot of entitlement and sandboxing errors, but fails in production (sideloaded archive). Development errors are as follow:
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)}>
(501) personaAttributesForPersonaType for type:0 failed with error Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.mobile.usermanagerd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.mobile.usermanagerd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction.}
Received port for identifier response: <> with error:Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}
The additional production error I'm encountering is the following:
Type "com.sunkensplashstudios.VRCRoboScout.csv" was expected to be declared and exported in the Info.plist of App.app, but it was not found.
I have, to the best of my knowledge, declared these data types properly:
Relevant code is below:
extension UTType {
static var CSVData: UTType { UTType(exportedAs: "com.sunkensplashstudios.VRCRoboScout.csv") }
}
struct CSVData: Transferable {
var csv_string: String
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(exportedContentType: .CSVData) { csv in
csv.csv_string.data(using: .utf8)!
}
}
}
ShareLink(item: CSVData(csv_string: csv_string), preview: SharePreview("VRC RoboScout Scouting Data.csv", image: Image(systemName: "tablecells"))) {
Text("Download").padding(10)
.background(settings.accentColor())
.foregroundColor(.white)
.cornerRadius(20)
}
Any ideas?
Scenario: The following Swift code uses NSItemProviderWriting to load a file from some data source async (The code actually just uses a for loop to simulate the time it needs to load the file). It returns the file url then. This code is used for drag & drop behavior in a macOS app from an app to another app. As the other app does only support file URLs as drop types, I can't send over the data itself.
class AnyFile: NSObject, NSItemProviderWriting {
let url: URL
init(url: URL) {
self.url = url
}
static var writableTypeIdentifiersForItemProvider: [String] {
return [UTType.fileURL.identifier]
}
func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, Error?) -> Void) -> Progress? {
let count = 100000
let progress = Progress(totalUnitCount: Int64(count))
print("a")
Task {
print("b")
for i in 0...100000 {
progress.completedUnitCount = Int64(i)
print(i)
}
print("c")
completionHandler(url.dataRepresentation, nil)
print("d")
}
print("e")
return progress
}
}
Problem: Drag & drop works, but when I start to drag the view (SwiftUI view using .onDrag), the view gets stuck as long as the loop is running. It is not clear to me why this happens as the loop us running inside a task. The console output also shows that progress is returned before the loop as finished. But still, it is stuck until the end of the loop. So the user experience is like not using async and the task.
Log output (shortened)
a
e
b
0
...
100000
c
d
Actual Question: Why is this Swift code for dragging files not behaving asynchronously even though it uses Task, completionHandler, and async/await constructs?
Alternatives tried:
I'm not bound to NSItemProviderWriting in particular. I have tried other ways, like Transferable, .draggable(), and NSItemProvider.registerFileRepresentation. But either they won't return a URL, or do not allow async at all. I also tried AppKit instead of SwiftUI with similar issues.
Hi All,
I have successfully implemented drag & drop of files from and to other apps on macOS successfully using different methods. Including NSFilePromiseProvider for example.
There is one app however, that I use on a regular basis, that only support file urls as drop types. So I have to use public.file-url to drag & drop files there. The problem is that the file does not exist when dragging starts. That's why I would like to send a URL promise to the app, instead of a file promise. I can't create the file beforehand because then I would need to create hundreds of large files which will just take up space.
So whenever I drag an item from my app to the other app, then the file shall be created and the url shall be sent to that app to be opened. But as the other app only checks the pasteboard for urls without handling promises, this is not working. I do have their code available, but can't change the code.
Question: Is there a way in Swift on macOS to drag and drop a an item to another app so that upon mouse up on the other app some async tasks is executed and at the end the other app receives the URL as a result of the async task?
Problem
When copyable is used with NavigationSplitView then it doesn't work
The menu Edit > Copy is disabled
Note
When copyable is not used with a NavigationSplitView and used only with a plain List then it works.
Question
Is there anything I am missing?
Feedback
FB12990593
Platform
macOS 14.0 Beta (23A5312d)
Xcode 15.0 beta 6 (15A5219j)
Steps to reproduce
Run the app on mac
Select some cars
Press Command C
Expected Behaviour
Menu Edit > Copy should be enabled
Pressing Command C should allow user to copy selected cars
Actual Behaviour
Menu Edit > Copy is disabled
Pressing Command C doesn't allow user to copy selected cars
Code
struct ContentView: View {
@State private var dataStore = DataStore()
var body: some View {
NavigationSplitView {
Color.brown
} detail: {
CarListView(dataStore: dataStore)
}
}
}
struct CarListView: View {
let dataStore: DataStore
@State private var selectedCarIDs = Set<UUID>()
var body: some View {
List(selection: $selectedCarIDs) {
ForEach(dataStore.cars) { car in
CarCell(car: car)
.draggable(car)
}
}
.copyable(selectedCars())
}
private func selectedCars() -> [Car] {
dataStore.cars.filter { selectedCarIDs.contains($0.id) }
}
}
struct CarCell: View {
let car: Car
var body: some View {
VStack(alignment: .leading) {
Text(car.name)
Text("\(car.price)")
}
}
}
@Observable
class DataStore {
var cars = [
Car(name: "aaa", price: 10),
Car(name: "bbb", price: 20),
Car(name: "ccc", price: 30),
Car(name: "ddd", price: 40)
]
}
struct Car: Codable, Transferable, Identifiable {
let id: UUID
let name: String
let price: Int
init(name: String, price: Int) {
self.id = UUID()
self.name = name
self.price = price
}
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .car)
}
}
extension UTType {
static let car = UTType("com.example.car")!
}
I've created a library that defines an encoded reference type, and was in the process of adding Transferrable conformance to the main class that represents the data. Doing so wants a type defined for the transferrable, so I'm adding a type for this data representation into the library.
The extension on UniformTypeIdentifiers is trivial, but I'd like to also mark that the type itself conforms to public.data (UTType.data). Since this is in a swift package, there isn't an application-relevant Info.plist that would normally hold these additional details.
Can I add the conformance through the library? Or is the whole aspect of Transferrable and associated UTTypes expected to be something only defined at the application level?
Hi everyone. I trying to implement some drag and drop functionality together with SwiftData. That requires my model to conform Transferable. And Transferable requires to conform Codable. My code doesn't compile with this error: Type 'Item' does not conform to protocol 'Decodable/Encodable'. The error appears right after I add @Model macro.
Is there a solution or a workaround? Here's my code:
@Model
final class Item: Transferable, Codable {
let createdAt: Date
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .myCustomType)
}
init() {
self.createdAt = .now
}
}
extension UTType {
static let myCustomType = UTType(exportedAs: "com.olexgreen.mytype")
}
Thank you very much
Hello,
I am building contact form that allows to attach screenshots and screen recordings. The PhotosPicker part is relatively straightforward but I am not sure how to properly import the selected items.
The binding is of type [PhotosPickerItem] which requires (at least for my current implementation) to first know if the item is image or video.
I have this not so pretty code to detect if the item is video:
let isVideo = item.supportedContentTypes.first(where: { $0.conforms(to: .video) }) != nil || item.supportedContentTypes.contains(.mpeg4Movie)
Which for screen recordings seems to work only because I ask about .mpeg4Movie and then I have this struct:
struct ScreenRecording: Transferable {
let url: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .mpeg4Movie) { video in
SentTransferredFile(video.url)
} importing: { received in
let copy = URL.temporaryDirectory.appending(path: "\(UUID().uuidString).mp4")
try FileManager.default.copyItem(at: received.file, to: copy)
return Self.init(url: copy)
}
}
}
Notice here I have just the .mpeg4Movie content type, I couldn't get it to work with more generic ones like movie and I am afraid this implementation could soon break if the screen recordings change video format/codec.
And finally my logic to load the item:
if isVideo {
if let movie = try? await item.loadTransferable(type: ScreenRecording.self) {
viewModel.addVideoAttachment(movie)
}
} else {
if let data = try? await item.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
viewModel.addScreenshotAttachment(uiImage)
}
}
}
I would like to make this more "future proof" and less error prone - particularly the screen recordings part.
I don't even need the UIImage since I am saving the attachments as files, I just need to know if the attachment is screenshot or video and get its URL.
Thanks!
I’m trying to use a ShareLink to share a PDF file. When using the file URL to the PDF directly, everything looks as I would expect:
let fileURL = URL(filePath: "…")
ShareLink(item: fileURL)
But in my actual app, the PDF isn’t available right away and is expensive to create, so I would like to only create it on demand. The documentation on FileRepresentation sounds to me like this is a use case for a custom type that implements Transferable with a FileRepresentation as its transferRepresentation. Before adding all the actual code to generate the PDF, I’m now trying to write a simple type that wraps a file URL and leads to the same results as using the URL directly. And I’m failing miserably.
This is what I tried:
struct PDFFile: Transferable {
var fileURL: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .pdf) { pdfFile in
SentTransferredFile(pdfFile.fileURL)
}
}
}
…and then in the view:
let fileURL = URL(filePath: "…")
let pdfFile = PDFFile(fileURL: fileURL)
ShareLink(
item: pdfFile,
preview: SharePreview(fileURL.deletingPathExtension().lastPathComponent, image: Image(systemName: "doc.richtext"), icon: Image(systemName: "doc"))
)
Why are no sharing services showing up? Why is there no icon?
I also tried using .fileURL as the exportedContentType, which then makes the sharing services show up, but actually sharing the file leads to an empty file being shared whose filename is garbage (it looks like the system tries to decode the PDF data as a UTF-8 string and use that as the filename).
So my question is: Is it possible to replicate the behavior of sharing a file URL with a custom type that asynchronously generates the data to share?
I've discovered an issue with using iOS 16's Transferable drag-and-drop APIs for SwiftUI. The dropDestination modifier does not work when applied to a subview of a List.
This code below will not work, unless you replace the List with a VStack or any other container (which, of course, removes all list-specific rendering).
The draggable modifier will still work and the item will drag, but the dropDestination view won't react to it and neither closure will be called.
struct MyView: View {
var body: some View {
List {
Section {
Text("drag this title")
.font(.largeTitle)
.draggable("a title")
}
Section {
Color.pink
.frame(width: 400, height: 400)
.dropDestination(for: String.self) { receivedTitles, location in
true
} isTargeted: {
print($0)
}
}
}
}
}
Has anyone encountered this bug and perhaps found a workaround?
In my app I try to use SwiftUI's ShareLink to offer sharing of the app's documents.
I followed this video for defining the exported type and the document type.
Unfortunately if I use any ShareLink initializer for sharing Transferable items, the option "save to files" is not offered on the displayed share sheet. (Only "copy" is offered, which works if pasted into the destination directory using the Files app, but that is not an acceptable workaround).
PS: com.example.transferabletestis defined as conforming to com.apple.package
import SwiftUI
import UniformTypeIdentifiers
extension UTType{
static let transferableTest = UTType(exportedAs: "com.example.transferabletest")
}
struct Document:Transferable{
static let filePackageURL = URL.documentsDirectory.appending(components: "0815.transferabletest")
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .transferableTest) { document in
_ = try? FileManager.default.createDirectory(at: Self.filePackageURL, withIntermediateDirectories: false)
FileManager.default.createFile(atPath: Self.filePackageURL.appending(components: "data").path(), contents: "Transferable Test\n".data(using: .utf8))
return SentTransferredFile(Document.filePackageURL)
}
}
}
struct ContentView: View {
var body: some View {
ShareLink("Share as tranferable item", item: Document(), preview: SharePreview("Test"))
}
}
Is this a bug?
What am I doing wrong?
Sharing the document using the ShareLink for URLs does offer "save to files" but I can't use that in my app for various reasons.
I'm having a hard time reconciling DocumentGroup with the new APIs using Transferable.
Setting up an app with DocumentGroup using a FileDocument type gives you undo/redo and file-specific app opening behavior out of the box (even though the navigation view implicitly present in DocumentGroup is a nightmare to work with).
Now with Transferable we're given the ability to set up representations to share, drag/drop, copy/paste, etc.
The point where these collide in a confusing way is in the .navigationDocument API., which sets up elements in the navigation bar to interact with a "document" that is Transferable.
This would be great to include in a DocumentGroup scene backed by a FileDocument, but FileDocument is not currently Transferable and furthermore the Navigation View underlying the DocumentGroup isn't easily exposed.
This really muddies the story around how to build document-based applications. Where does DocumentGroup fit in now that Transferable exists? Should I be providing my own conformance to Transferable on my FileDocument, reach down into the implicit NavigationView of DocumentGroup to get the new .navigationDocument functionality? Is DocumentGroup soon to be deprecated (or at least not for a more sophisticated use case) and apps should be built with Transferrable types in a normal WindowGroup that implements all of the other goodies that exist in DocumentGroup?
Any clarity around the intention with DocumentGroup and how such an app would fit into a world of Transferables would be greatly appreciated!
Overview
I am bit confused regarding drag and drop on SwiftUI
I think there are 2 approaches but I am stuck with both approaches
WWDC22
When using the new draggable, dropDestination, Transferable API, only single items are draggable. Multiple items in a list are not draggable. I have filed a feedback FB10128110
WWDC21
I have faced a couple of issues for drag and drop introduced in WWDC21 (onDrag, onDrop, itemIdentifier), the Feedback ids are FB9854301, FB9854569, FB9855245, FB9855532, FB9855567, FB9855575. It contains sample projects, would really appreciate if someone could have a look it.
Note: All feedbacks include a sample project with detail steps and some even have screenshots and videos
Questions:
If my approach is wrong or if I am missing something?
Unfortunately I didn't manage to get a SwiftUI lab session (got cancelled), so please help me with these issues.