Прикрепить видео, помимо фото

Мне нужно отправлять фото и видео на сервер вместе с текстом из форм. При нажатии на кнопку "Прикрепить файл", появляется всплывающее окно с медиа галереей телефона. Фото корректно выбирается из галереи и добавляется к отправке. Но в галерее не выводятся видео.

На форумах почти везде показывают добавление именно фото, а видео нет. Кое где нашёл совет, что для вывода в галерее видео нужно использовать AVKit.

Как добавить поддержку видео?

MediaPicker.swift:

import Foundation
import SwiftUI

class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    @Binding var presentationMode: PresentationMode
    @Binding var image: Image?

    init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) {
        _presentationMode = presentationMode
        _image = image
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        image = Image(uiImage: uiImage)
        presentationMode.dismiss()

    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        presentationMode.dismiss()
    }

}

struct MediaPicker: UIViewControllerRepresentable {

    @Binding var image: Image?
    @Environment(\.presentationMode)

    var presentationMode

    func makeCoordinator() -> Coordinator {
        return Coordinator(presentationMode: presentationMode, image: $image)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<MediaPicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<MediaPicker>) {
    }

}

extension View {

    public func asUIImage() -> UIImage {
        let controller = UIHostingController(rootView: self)

        controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
        UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)

        let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
        controller.view.bounds = CGRect(origin: .zero, size: size)
        controller.view.sizeToFit()

        let image = controller.view.asUIImage()
        controller.view.removeFromSuperview()
        return image
    }

}

extension UIView {

    public func asUIImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)

        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }

}

ContentView.swift:

import SwiftUI

struct ContentView: View {

    @State private var checkRequestStatus: Bool = false
    @State private var selectedMedia: Image?
    @State private var showMediaPicker: Bool = false

    var body: some View {

        NavigationView {

            VStack {
                Button(action: {
                    self.showMediaPicker.toggle()
                }, label: {
                    Text("Прикрепить файл")
                        .padding(.vertical, 5)
                        .padding(.horizontal, 15)
                        .foregroundColor(.black)
                        .background(Color("LightGrayColor"))
                        .multilineTextAlignment(.center)
                        .overlay(
                            RoundedRectangle(cornerRadius: 5)
                                .stroke(Color.black, lineWidth: 1)
                        )
                })

                if ((self.selectedMedia) != nil) {
                    self.selectedMedia?
                        .resizable()
                        .scaledToFit()
                        .frame(minWidth: 0, maxWidth: .infinity)
                }

                Button(action: {
                    let uiImage: UIImage = self.selectedMedia.asUIImage()
                    let imageType: String = "image"
                    let imageData: Data = uiImage.jpegData(compressionQuality: 0.5) ?? Data()
                    let imageStr: String = imageData.base64EncodedString()
                    let shareHelper: ShareHelper = ShareHelper(message: "content", user: "user", email: "email", media: imageStr, type: imageType)

                    shareHelper.RequestPost { (dataString) in
                        print("File was sent")
                    }
                }, label: {
                    Text("Отправить")
                })
                .frame(width: 150)
                .padding(10)
                .foregroundColor(self.checkRequestStatus ? Color.black : Color.gray)
                .background(Color("LightGrayColor"))
                .overlay(
                    RoundedRectangle(cornerRadius: 5)
                        .stroke(self.checkRequestStatus ? Color.black : Color.gray, lineWidth: 1)
                )
                .alert(isPresented: $checkRequestStatus) { () -> Alert in
                    self.checkRequestStatus = true
                    self.showMediaPicker = true
                    return Alert(title: Text("Спасибо!"), message: Text("Новость успешно отправлена"), dismissButton: .default(Text("Закрыть")))
                }
                .disabled(!self.checkRequestStatus)

            }
            .sheet(isPresented: $showMediaPicker, content: {
                MediaPicker(image: self.$selectedMedia)
            })

        }

    }

}

Ответы (1 шт):

Автор решения: VAndrJ

Чтобы видео выводилось в галерее сделайте:

import MobileCoreServices

и для UIImagePickerController пропишите:

...
let picker = UIImagePickerController()
picker.mediaTypes = [kUTTypeImage, kUTTypeMovie].map { $0 as String }
...

Дефолтное значение mediaTypes только картинки: kUTTypeImage.

→ Ссылка