Search code examples
swiftuiimagepickercontrollerswift5messagekit

UIImagePickerController not initiating next function


I'm using Swift 5 and have integrated MessageKit into my app. Here's the expected functionality:

  1. User selects the image via picker
  2. uploadImage function is initiated
  3. Image is uploaded and displayed

What's actually happening:

  1. User selects the image via picker
  2. Nothing happens from there.

I'm not getting a single error message. I've put in print statements to see if it's even entering the uploadImage() function but it's not kicking off. I've change the uipickerimagecontroller code to exact code in other places of my app that is working and even that's not kicking off the function. I know my code isn't pretty but I'm still learning (please don't judge lol). Can anyone help:

Variable setup

private var isSendingPhoto = true {
  didSet {
    DispatchQueue.main.async {
      self.messageInputBar.leftStackViewItems.forEach { item in
        item.inputBarAccessoryView?.isUserInteractionEnabled = !self.isSendingPhoto
      }
    }
  }
}

ViewDidLoad

    messagesCollectionView.messagesDataSource = self
    messagesCollectionView.messagesLayoutDelegate = self
    messageInputBar.delegate = self as? InputBarAccessoryViewDelegate
    messagesCollectionView.messagesDisplayDelegate = self
    title = "MaybeDrinks"

    // 1
    let cameraItem = InputBarButtonItem(type: .system)
    cameraItem.tintColor = .primary
    cameraItem.image = #imageLiteral(resourceName: "camera")

    // 2
    cameraItem.addTarget(
      self,
      action: #selector(cameraButtonPressed),
      for: .primaryActionTriggered
    )
    cameraItem.setSize(CGSize(width: 60, height: 30), animated: false)

    messageInputBar.leftStackView.alignment = .center
    messageInputBar.setLeftStackViewWidthConstant(to: 50, animated: false)
    messageInputBar.setStackViewItems([cameraItem], forStack: .left, animated: false) // 3
}

    private func sendPhoto(_ image: UIImage) {
          isSendingPhoto = true

          uploadImage(image) { [weak self] url in
            guard let `self` = self else {
              return
            }
            self.isSendingPhoto = false

            guard let url = url else {
              return
            }

            var message = Message(messageuser: self.sender, image: image)
            message.downloadURL = url

            self.save(message)
            self.messagesCollectionView.scrollToBottom()
          }
        }
    func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
          picker.dismiss(animated: true, completion: nil)

          // 1
          if let asset = info[.phAsset] as? PHAsset {
            let size = CGSize(width: 500, height: 500)
            PHImageManager.default().requestImage(
              for: asset,
              targetSize: size,
              contentMode: .aspectFit,
              options: nil) { result, info in
                print("I'm in image picker")
              guard let image = result else {
                return
              }

              self.sendPhoto(image)
            }

          // 2
          } else if let image = info[.originalImage] as? UIImage {
            sendPhoto(image)
          }
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
          picker.dismiss(animated: true, completion: nil)
        }
        // MARK: - Actions

        @objc private func cameraButtonPressed() {
          let picker = UIImagePickerController()
            picker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
          picker.allowsEditing = true

          if UIImagePickerController.isSourceTypeAvailable(.camera) {
            picker.sourceType = .camera
          } else {
            picker.sourceType = .photoLibrary
          }

          present(picker, animated: true, completion: nil)
        }

Upload Image function

private func uploadImage(_ image: UIImage, completion: @escaping (URL?) -> Void) {
  print("im in upload")

  // STEP 1. Declare URL, Request and Params
  let url = URL(string: "https://localhost/messagepost.php")!

  // declaring reqeust with further configs
  var request = URLRequest(url: url)

  // POST - safest method of passing data to the server
  request.httpMethod = "POST"

         // values to be sent to the server under keys (e.g. ID, TYPE)
  let params = ["sender_id": user_id, "uuid": uuid, "sender": me, "recipient_id": rid, "recipient": recipient, "puuid": puuid]

  // body
  let boundary = "Boundary-\(UUID().uuidString)"
  request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

  // Compressing image and converting image to 'Data' type
  guard let scaledImage = image.scaledToSafeUploadSize,
    let data = scaledImage.jpegData(compressionQuality: 0.4) else {
    return
  }

  // assigning full body to the request to be sent to the server
  request.httpBody = createBodyWithParams(params, filePathKey: "file", imageDataKey: data, boundary: boundary)
    print(request.httpBody as Any, "\(puuid).jpg")

  URLSession.shared.dataTask(with: request) { (data, response, error) in
      DispatchQueue.main.async {

          // error occured
          if error != nil {
              Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
              return
          }


          do {

              // save mode of casting any data
              guard let data = data else {
                  Helper().showAlert(title: "Data Error", message: error!.localizedDescription, in: self)
                  return
              }

              // fetching JSON generated by the server - php file
              let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary

              // save method of accessing json constant
              guard let parsedJSON = json else {
                  return
              }

              // uploaded successfully
              if parsedJSON["status"] as! String == "200" {
                let newurl = parsedJSON["path"]
                print("did you upload", newurl as Any)
                print("did you upload", parsedJSON["message"] as Any)
                self.isSendingPhoto = true
                  guard let url = newurl else {
                    return
                  }
                  //uploadImage(image)
                var message = Message(messageuser: self.sender, image: image)
                message.downloadURL = url as? URL

                    self.save(message)
                    self.messagesCollectionView.scrollToBottom()


              } else {

                  // show the error message in AlertView
                  if parsedJSON["message"] != nil {
                      let message = parsedJSON["message"] as! String
                      Helper().showAlert(title: "Error", message: message, in: self)
                    print("where am i", parsedJSON["message"] as Any)
                  }

              }

          } catch {
              Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
            print("where am i 2")
          }

      }
  }.resume()

  let imageName = [UUID().uuidString, String(Date().timeIntervalSince1970)].joined()


}

private func save(_ message: Message) {


    self.messagesCollectionView.scrollToBottom()

}

Solution

  • Make sure your view controller declares conformance to both UIImagePickerControllerDelegate and UINavigationControllerDelegate in either the class declaration:

    class DirectMessageViewController: MessagesViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        [...]
    }
    

    or in one or more extensions:

    extension DirectMessageViewController: UIImagePickerControllerDelegate {
        [...]
    }
    
    extension DirectMessageViewController: UINavigationControllerDelegate {
        [...]
    }