Swift 4 - Obtenha um progresso de upload de imagem usando URLSession

Eu tenho esse tipo de código abaixo

func upload(){
    let img = UIImage(named: "1")
    let imgData = UIImageJPEGRepresentation(img!, 1)
    let data = imgData?.base64EncodedString()

    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    request.setValue("\(auth)", forHTTPHeaderField: "Authorization")
    request.setValue("application/xml", forHTTPHeaderField: "Content-Type")

    var postString = "<uploadrequest>"
    postString += "<folderid>123</folderid>"
    postString += "<folder_name>images</folder_name>"
    postString += "<image_byte>\(data!)</image_byte>"
    postString += "</uploadrequest>"

    request.httpBody = postString.data(using: .utf8)

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

    let task = session.uploadTask(with: request, from: imgData!, completionHandler: {
        (data, response, error) -> Void in

        if let error = error {
            print(error)
            return
        }
        if let data = data {
            _ = self.parseJsonData(data: data)
        }
    })

    task.resume()
}

func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
    print("sent:", totalBytesSent, "from:", totalBytesExpectedToSend)

    let size = totalBytesSent / totalBytesExpectedToSend
    self.progressbar.progress = Float(size)
}

Meu objetivo é fazer upload de uma imagem usando a API e obter o progresso do upload também. A imagem é convertida em base64 e inserida em<image_byte>\(data!)</image_byte> na coluna de mensagens da API.

Então o que eu consegui foi algo como isto:

sent: 32768 de: 927220 enviado: 65536 de: 927220 enviado: 131072 de: 927220 enviado: 163840 de: 927220 enviado: 262144 de: 927220 enviado: 294912 de: 927220 enviado: 360448 de: 927220 enviado: 393216 de: 927220 enviado : 425984 de: 927220 enviado: 491520 de: 927220 enviado: 524288 de: 927220 enviado: 557056 de: 927220 enviado: 589824 de: 927220 enviado: 622592 de: 927220 enviado: 655360 de: 927220 enviado: 688128 de: 927220 enviado: 720896 de: 927220 enviado: 786432 de: 927220 enviado: 819200 de: 927220 enviado: 851968 de: 927220 enviado: 927220 de: 927220 Domínio de erro = NSCocoaErrorDomain Code = 3840 "O texto JSON não foi iniciado com matriz ou objeto e opção para permitir fragmentos não conjunto." UserInfo = {NSDebugDescription = O texto JSON não foi iniciado com matriz ou objeto e opção para permitir fragmentos não configurados.}

Mas se eu estiver usando outros métodos como este (sem uploadTask), ele funcionará bem, mas não terá progresso no upload.

let task = URLSession.shared.dataTask(with: request, completionHandler: {
        (data, response, error) -> Void in

        if let error = error {
            print(error)
            return
        }
        if let data = data {
            _ = self.parseJsonData(data: data)
        }
    })

Eu tenteiAlamofire também.Alamofire comrequest função @ foi bem-sucedida, mas ainda não deu andamento ao upload eAlamofire comuploadfunction (multipartformData) comete este erro:

responseSerializationFailed (motivo: Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed (erro: Domínio do erro = NSCocoaErrorDomain Code = 3840 "Valor inválido no caractere 3." UserInfo = {NSDebugDescription = Valor inválido no caractere 3.})

Quero saber se cometo algum erro no meu código. Você poderia me dizer o que devo fazer com o meu código? Ou o problema era minha API porque minha API apenas aceita umbase64 código?

Se você quiser ver meuAlamofire código, erah

or favor, alguém me ajude a resolver este problem

Obrigado! :)

EDIT 1

Este é o resultado da função de solicitação (sem função de upload)

{
    "media_preview" =     {
        "image_media" =         {
            fileid = 4928501;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "product\\66861/images800\\";
            height = 533;
            src = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 800;
        };
        "medium_media" =         {
            fileid = 4928503;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "product\\66861/images500\\";
            height = 333;
            src = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 500;
        };
        "small_media" =         {
            fileid = 4928503;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "\product\\66861/images300\\";
            height = 200;
            src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 300;
        };
        "source_media" =         {
            fileid = 4928499;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "\\product\\66861images\\";
            height = 666;
            src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 999;
        };
        "thumbnail_media" =         {
            fileid = 4928507;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = \\product\\66861/thumb\\";
            height = 150;
        ,    src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 150;
        };
    };
    responsestatus =     {
        "access_token" = "<null>";
        code = 00;
        description = Success;
    };
}

EDIT 2 Este é o código deparseJsonData(data: Data)

func parseJsonData(data: Data) {
    do {
        let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
        print(jsonResult!)
    } catch {
        print(error)
    }
}

questionAnswers(2)

yourAnswerToTheQuestion