1

I'm trying to open the finder using Mac Catalyst and get images.

At first, I tried the below code, but Xcode says 'NSOpenPanel' is unavailable in Mac Catalyst .

 private func selectFile() {
        NSOpenPanel.openImage { (result) in
            if case let .success(image) = result {
                self.image = image
            }
        }
    }

So I tried this solution, this time Compile was successful, but when I click the button to open finder I got this error message: Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)

My Final Code is below

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack{
 
            Button("Choose file") {
                let picker = DocumentPickerViewController(
                    supportedTypes: ["log"],
                    onPick: { url in
                        print("url : \(url)")
                    },
                    onDismiss: {
                        print("dismiss")
                    }
                )
                UIApplication.shared.windows.first?.rootViewController?.present(picker, animated: true)
            }
            
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class DocumentPickerViewController: UIDocumentPickerViewController {
    private let onDismiss: () -> Void
    private let onPick: (URL) -> ()

    init(supportedTypes: [String], onPick: @escaping (URL) -> Void, onDismiss: @escaping () -> Void) {
        self.onDismiss = onDismiss
        self.onPick = onPick

        super.init(documentTypes: supportedTypes, in: .open)

        allowsMultipleSelection = false
        delegate = self
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension DocumentPickerViewController: UIDocumentPickerDelegate {
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        onPick(urls.first!)
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        onDismiss()
    }
}

How can I solve this issue?

Claus Jørgensen
  • 25,882
  • 9
  • 87
  • 150
Seungjun
  • 874
  • 9
  • 21
  • 1
    I had a similar error on the same code @yuto suggested. In my case, I was missing "User Selected files" permission. – Vladimir Aug 02 '21 at 21:06

1 Answers1

1

In my macCatalyst app, I use a UIViewControllerRepresentable to show a UIDocumentPickerViewController

@Binding to your main view so you can reference that data from the selected file

struct DocumentImportViewController: UIViewControllerRepresentable {
@Binding var imgData:Data! //This doesn't need to be a "Data"

func makeCoordinator() -> Coordinator {
    return Coordinator(self)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentImportViewController>) -> UIDocumentPickerViewController {
    let vc = UIDocumentPickerViewController(forOpeningContentTypes: [.image], asCopy: true)
    vc.delegate = context.coordinator
    return vc
}

func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<DocumentImportViewController>) {
    
}
}

Coordinator for delegates

extension DocumentImportViewController{
class Coordinator: NSObject, UIDocumentPickerDelegate {
    var parent: DocumentImportViewController
    
    init(_ parent: DocumentImportViewController) {
        self.parent = parent
    }

    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        parent.imgData = //get image from url
    }
}}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Yuto
  • 658
  • 2
  • 8
  • 20
  • Thank you so much for taking the time to write a detailed explanation. Can I have one question?. Could you provide more details about '/get image from url'?. If I correctly understood, I have to put the URL of the image at the comment, but how can I get the URL of the image? – Seungjun Nov 13 '20 at 11:29
  • 1
    So, the way I wrote it made it kind of confusing, so let me clarify. "didPickDocumentsAt" has "urls" which provide a "[URL]" of the files selected. From the url, you can change it to a type you like, ex. Data. – Yuto Nov 14 '20 at 04:49