尝试运行任务时,发送图像,获取错误代码= 13“查询已取消”

I am currently using an image picker for an iOS app to get a picture from the camera role, then trying to send it to a PHP Script on a web server to save the image at the other end.

When the the line of code task.resume() runs, however, this error is thrown:

[discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}

The image does not save at the destination either, after this happens.

I've read several other posts about this error, and have tried exposing a the didFinishPickingMediaWithInfo to objective-c with @objc.

I've got the Privacy - Photo Library Usage Description assigned in the plist. I've also allowed Arbitrary Loads.

Through all this the error still occurs, so if anyone can spot anything wrong with my code it would help a lot. I'll also add the PHP Script so you can see where the data is sent to, thanks.

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDataDelegate {

    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var uploadButton: UIButton!
    @IBOutlet weak var progressView: UIProgressView!
    @IBOutlet weak var progressLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        checkPermission()
    }

    func checkPermission() {
        let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
        switch photoAuthorizationStatus {
        case .authorized:
            print("Access is granted by user")
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({
                (newStatus) in
                print("status is \(newStatus)")
                if newStatus ==  PHAuthorizationStatus.authorized {
                    /* do stuff here */
                    print("success")
                }
            })
            print("It is not determined until now")
        case .restricted:
            // same same
            print("User do not have access to photo album.")
        case .denied:
            // same same
            print("User has denied the permission.")
        }
    }

    @IBAction func uploadTapped(_ sender: UIButton) {
        let pickerController = UIImagePickerController()
        pickerController.delegate = self
        pickerController.sourceType = UIImagePickerController.SourceType.photoLibrary

        self.present(pickerController, animated: true, completion: nil)
    }

    @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        imageView.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage

        imageView.backgroundColor = UIColor.clear
        self.dismiss(animated: true, completion: nil)

        uploadImage()
    }

    func uploadImage() {
        let imageData = imageView.image!.jpegData(compressionQuality: 1)

        if imageData == nil {
            return
        }

        self.uploadButton.isEnabled = false

        let uploadScriptURL = NSURL(string: "I've removed the URL for this question, but a valid URL to the PHP goes here")
        var request = URLRequest(url: uploadScriptURL! as URL)
        request.httpMethod = "POST"
        request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")

        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)

        let task = session.uploadTask(with: request, from: imageData!)
        print(imageData!)
        task.resume()
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        let alert = UIAlertController(title: "Alert", message: error?.localizedDescription, preferredStyle: .alert)
        self.present(alert, animated: true, completion: nil)
        self.uploadButton.isEnabled = true
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
        let uploadProgress:Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
        progressView.progress = uploadProgress
        let progressPercent = Int(uploadProgress * 100)
        progressLabel.text = "\(progressPercent)%"
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        self.uploadButton.isEnabled = true
    }
}

PHP Script:

<?php
    $target_dir = "uploads";
    if(!file_exists($target_dir))
    {
        mkdir($target_dir, 0777, true);
    }
    $target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {
        echo json_encode([
            "Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
            "Status" => "OK"
        ]);
    } else {
        echo json_encode([
            "Message" => "Sorry, there was an error uploading your file.",
            "Status" => "Error"
        ]);
    }

So it turns out my issue was not caused by this error, and it seems that the error does not actually have any effect on the code - It seems it can be ignored.

In my case, the code wasn't working due to an oversight on my end. The image I was trying to send was 2.2MB, and I hadn't realised it was returning a HTML error code 413, due to the cap being 2MB on the server I was testing.

If you are having issues with a task like this failing make sure to print out response in the didReceive response function of the urlSession. That way you can check any HTML errors that get returned.