Moya: Upload progress incorrect due to wrong payload size

Version 11.0.0-beta.2 (and 10 as well)

Using Task’s.requestData(Data) leads to progress jumping straight to 1.0 due to size not being recognized properly. The same is not true just using straight up Alamofire.

Reported progress using Moya

πŸ”’ preparing HTTP Task: .requestData with 2575959 bytes of data
(moya) πŸ’š progress: ProgressResponse(response: nil, progressObject: Optional(<NSProgress: 0x1d413ee60> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 11 of 11  ))
(moya) πŸ’š progress: ProgressResponse(response: Optional(Status Code: 200, Data Length: 11), progressObject: Optional(<NSProgress: 0x1d413ee60> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 11 of 11  ))
πŸ’š Optional(200)

Reported progress using Alamofire

πŸ”’ length = 2566021
(alamo) ❀️ progress: <NSProgress: 0x1d012e100> : Parent: 0x0 / Fraction completed: 0.0032 / Completed: 8192 of 2566021  
(alamo) ❀️ progress: <NSProgress: 0x1d012e100> : Parent: 0x0 / Fraction completed: 0.7119 / Completed: 1826816 of 2566021  
(alamo) ❀️ progress: <NSProgress: 0x1d012e100> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 2566021 of 2566021  
❀️ Optional(200)

Moya Service

enum ImageService {
    case upload(vehicleId: String, data: Data, id: String, token: String)
}

extension ImageService : TargetType {
    var baseURL: URL { return URL(string: "https://putsreq.com")! }
    
    var path: String { return "/Rvq2FIlE001dZLisBGxs" }
    
    var method: Moya.Method { return .post }
    
    var sampleData: Data { return Data() }
    
    var task: Task {
        switch self {

        case .upload(_, let data, _, _):
            print("πŸ”’ preparing HTTP Task: .requestData with \(data.count) bytes of data")
            
            return .requestData(data)
        }
    }
    
    var validate: Bool { return false }
    
    var headers: [String: String]? {
        return ["Content-Type": "image/jpeg"]
    }
}

Moya Service invocation

    private func uploadWithMoyaTest(_ data: Data) {
        
        imageProvider.request(.upload(vehicleId: "1", data: data, id: "123", token: "456"), callbackQueue: DispatchQueue.main,
                              progress: { progress in print("(moya) πŸ’š progress: \(progress)") }
        ) { result in
            
            if case let .success(moyaResponse) = result {
                if let _ = try? moyaResponse.filterSuccessfulStatusCodes() {
                    print("πŸ’š \(moyaResponse.response?.statusCode)")
                    return
                }
            }
            print("πŸ’š Upload failed")
        }
    }

Alamo Service

class AlamoImageService {
    
    public static func upload(_ data: Data) throws -> UploadRequest {
        
        print("πŸ”’ length = \(data.count)")
        
        let req = try URLRequest(url: "https://putsreq.com/B7LUB963aaAadyJ0XCwN".asURL(), method: HTTPMethod.post, headers: ["Content-Type":"image/jpeg"])
        
        return Alamofire.upload(data, with: req)
    }
}

Alamo invocation

    private func uploadWithAlamoTest(_ data: Data) {
        do {
            let uploadRequest = try AlamoImageService.upload(data)
            
            uploadRequest.uploadProgress { progress in
                print("(alamo) ❀️ progress: \(progress)")
            }
            
            uploadRequest.response { response in
                print("❀️ \(response.response?.statusCode)")
            }
        } catch {
            print("❀️ Upload failed")
        }
    }

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Then I’d vote for a new case uploadData(Data) in Task.swift that maps to the Alamofire.upload API. In a current implementation of mine I also save data to a temporary file just to get the upload progress