I am trying to implement a feature that allows a user to set their profile picture.
I am wrapping a UIImagePIckerController
using a UIViewControllerRepresentable
.
My Coordinator
class is handling the delegate method didFinishPickingMediaWithInfo
which returns the image picked.
Currently, I send this image to the reducer via an action to be stored in the state.
What is the best practice for a situation like this? Is it preferred to instead write the image to a URL and send that back instead? Since now my state is exposed to the UIImage type.
// ImagePicker.swift
import SwiftUI
import ComposableArchitecture
struct ImagePicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
let viewStore: ViewStore<ImagePickerState, ImagePickerAction>
func makeUIViewController(
context: UIViewControllerRepresentableContext<ImagePicker>
) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(
_ uiViewController: UIImagePickerController,
context: UIViewControllerRepresentableContext<ImagePicker>
) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
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.viewStore.send(.imagePicked(image: uiImage))
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
public struct ImagePickerState: Equatable {
var showingImagePicker: Bool
var image: UIImage?
}
public enum ImagePickerAction: Equatable {
case setSheet(isPresented: Bool)
case imagePicked(image: UIImage)
}
public struct ImagePickerEnvironment {
}
public let imagePickerReducer = Reducer<ImagePickerState, ImagePickerAction, ImagePickerEnvironment> { state, action, environment in
switch action {
case .setSheet(isPresented: true):
state.showingImagePicker = true
return .none
case .setSheet(isPresented: false):
state.showingImagePicker = false
return .none
case let .imagePicked(image):
state.image = image
return .none