How to properly use SwiftUI's Photo Picker to upload image?

I am using SwiftUI's native image picker and selecting/loading images works great. What I can't figure out is how to call the selected image when uploading the image to firebase. In my UploadPostView, I can't figure out what to call for the image in viewModel.uploadPost(caption: caption, image: <??>)) 

I've tried calling the selectedImage but I get the error that it is not a UIImage.. I thought I had done the work to convert the data in to a UIImage in my imagepicker. Anyways, I am new to Swift and I feel like I'm missing something obvious so any help is appreciated!

UploadPostView

  @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

  @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

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
    }
  }
}

Replies

I've tried calling the selectedImage but I get the error that it is not a UIImage.

I suspect that you are probably referring to a compilation error, but I don't see selectedImage in your code. It may be helpful if you posted the full error message!