Keep getting a delay and warning message on an ImagePicker when opening and selecting an image from Photo Library in Swift

26 views Asked by At

From the code below everything is working fine except a repetitive delay when opening the image picker (in a sheet) and selecting the image once inside. I end getting the error below when I open the image picker:

<0x103107e90> Gesture: System gesture gate timed out.

And the warning when I pick the image from the picker:

"Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""

I have already added the permission requirements as part of the info.plist file under "Privacy - Photo Library Usage Description" and still have the issue.

This is the image picker and underneath it is the button I am using in the parent view to pull the image picker up as a sheet:

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var selectedImage: UIImage?
    @Environment(\.presentationMode) var presentationMode
    @Binding var choseImageFromCameraRoll: Bool

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker

        init(parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(
            _ picker: UIImagePickerController,
            didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
        ) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.selectedImage = uiImage
                parent.choseImageFromCameraRoll = true
            }
            parent.presentationMode.wrappedValue.dismiss()
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            parent.choseImageFromCameraRoll = false
            parent.selectedImage = nil
            parent.presentationMode.wrappedValue.dismiss()
        }
    }

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

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = .photoLibrary
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}

And below is the button in the main view to pull up the image picker

Button {
                                    if !videoChosen {
                                        isImagePickerPresented = true
                                    }
                                } label: {
                                    Circle()
                                        .frame(width: 60)
                                        .foregroundStyle(.black.opacity(0.5))
                                        .overlay {
                                            Image(systemName: "photo")
                                                .resizable()
                                                .aspectRatio(contentMode: .fit)
                                                .frame(width: 30)
                                                .fontWeight(.medium)
                                                .foregroundStyle(.white)
                                                .opacity(0.85)
                                        }
                                }
                                .padding(.leading, 45)
                                .sheet(isPresented: $isImagePickerPresented) {
                                    ImagePicker(selectedImage: $selectedImage, choseImageFromCameraRoll: $choseImageFromCameraRoll)
                                }
1

There are 1 answers

0
malhal On

Need to change Coordinator(parent: self) to Coordinator() the representable is not an object so can't use self.

Need to implement updateUIViewController to both set a closure on the coordinator that updates the binding and use the current value of the biding to update the view controller, e.g. like this pseudo:

updateUIViewController {
 coordinator.photoPicked = nil
 picker.photo = selectedImage
 coordinator.photoPicked = { photo in
   selectedImage = photo
 }
}