Как правильно использовать средство выбора фотографий SwiftUI для загрузки изображения?
Я использую собственный инструмент выбора изображений SwiftUI, и выбор/загрузка изображений отлично работает. Чего я не могу понять, так это как вызвать выбранное изображение при загрузке изображения в firebase. В моем UploadPostView я не могу понять, что вызывать для изображения вviewModel.uploadPost(caption: caption, image: <??>))
Я пытался вызвать selectedImage, но получаю сообщение об ошибке, что это не UIImage. Я думал, что проделал работу по преобразованию данных в UIImage в моем средстве выбора изображений. В любом случае, я новичок в Swift, и я чувствую, что упускаю что-то очевидное, поэтому любая помощь приветствуется!
ЗагрузитьPostView
struct UploadPostView: View {
@StateObject var imagePicker = ImagePicker()
@State private var caption = ""
@Environment(\.presentationMode) var mode
@ObservedObject var viewModel = UploadPostViewModel()
var body: some View {
NavigationView {
VStack {
HStack(alignment: .top, spacing: 16) {
if let user = AuthViewModel.shared.currentUser {
KFImage(URL(string: user.profileImageUrl ?? ""))
.resizable()
.scaledToFill()
.frame(width: 64, height: 64)
.cornerRadius(10)
}
TextField("Enter your post here", text: $caption, axis: .vertical)
.lineLimit(5...10)
}.padding()
Spacer()
if let image = imagePicker.image {
HStack {
ZStack (alignment: .top) {
image
.resizable()
.scaledToFill()
.frame(width: 100, height: 100)
.cornerRadius(4)
Button {
self.imagePicker.image = nil
} label: {
Image(systemName: "xmark")
.frame(width: 24, height: 24)
.foregroundColor(.white)
.padding(4)
.background(.black)
.clipShape(Circle())
}
.offset(x: 45, y: -15)
}
Spacer()
}
.padding()
}
HStack (spacing: 24) {
Text("Add to your post")
.foregroundColor(Color(.darkGray))
Spacer()
PhotosPicker(selection: $imagePicker.imageSelection) {
Image(systemName: "photo")
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
}.foregroundColor(Color(.darkGray))
Button {
} label: {
Image(systemName: "at")
.resizable()
.scaledToFit()
.frame(width: 22, height: 22)
}.foregroundColor(Color(.darkGray))
}
.padding()
}
.onReceive(viewModel.$didUploadPost) { success in
if success {
mode.wrappedValue.dismiss()
}
}
.navigationTitle("Create Post")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
mode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.resizable()
.scaledToFit()
.frame(width: 18, height: 18)
.foregroundColor(Color(.darkGray))
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
viewModel.uploadPost(caption: caption, image: image))
} label: {
Text("Post")
.font(.system(size: 18))
.bold()
}
}
}
}
}
}
UploadPostViewModel
class UploadPostViewModel: ObservableObject {
@Published var didUploadPost = false
@Published var didDeletePost = false
let service = PostService()
func uploadPost(caption :String, image: UIImage?) {
service.uploadPost(caption: caption, image: image) { success in
if success {
//dismiss screen
self.didUploadPost = true
} else {
// show error message to user..
}
}
}
}
ImagePicker
@MainActor class ImagePicker: ObservableObject {
@Published var image: UIImage?
@Published var imageSelection: PhotosPickerItem? {
didSet {
if let imageSelection {
Task {
try await loadTransferable(from: imageSelection)
}
}
}
}
func loadTransferable(from imageSelection: PhotosPickerItem?) async throws {
do {
if let data = try await imageSelection?.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
self.image = uiImage
}
}
} catch {
print(error.localizedDescription)
image = nil
}
}
}