3

I would like to add a progress bar for knowing exactly the percent of upload of my video, but impossible to call the didCompleteWithError, didReceive response, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalB etc...

I added well the delegate, but impossible to catch the problem.

@objcMembers open class DAL : NSObject
{
    var response: URLResponse?
    var session: URLSession?
    var uploadTask: URLSessionUploadTask?
    let opQueue = OperationQueue()

    static let sharedInstance = DAL()
    fileprivate let showLogs = true

    var WSURL:String =  SERVER_PROTOCOL + DOMAIN_NAME_ADDRESS //"http://localhost:3000"
    var eventKey:String = EVENT_TO_USE
}

In another class:

extension DAL: URLSessionDelegate,URLSessionDataDelegate, URLSessionTaskDelegate
{

        func uploadVideo(_ videoPath: String, fileName: String, eventId: Int, contactId: Int, type: Int, callback: @escaping (_ data:Data?, _ resp:HTTPURLResponse?, _ error:NSError?) -> Void)
            {
                // let filePath = video

                // let videoFileURL = NSURL(fileURLWithPath: videoPath)
                var video_data: NSData?
                do {
                    video_data = try NSData(contentsOfFile: (videoPath), options: NSData.ReadingOptions.alwaysMapped)
                } catch _ {
                    video_data = nil
                    return
                }

                let WSURL:String =  "https://" + "ren.newp.fr/node"



            let requestURLString = "\(WSURL)/regtions/lead/photo//"
            let url = URL(string: requestURLString)
            #if DEBUG
            print(requestURLString)
            #endif
            let request = NSMutableURLRequest(url: url!)
            request.httpMethod = "POST"

            let boundary = generateBoundaryString()

            //define the multipart request type
            request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

            let body = NSMutableData()
            let mimetype = "video/mp4"

            //define the data post parameter

            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"eventId\"\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append("\(eventId)\r\n".data(using: String.Encoding.utf8)!)

            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"contactId\"\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append("\(contactId)\r\n".data(using: String.Encoding.utf8)!)

            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"type\"\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append("\(type)\r\n".data(using: String.Encoding.utf8)!)

            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(fileName)\"\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append(video_data! as Data)
            body.append("\r\n".data(using: String.Encoding.utf8)!)

            body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)

            request.httpBody = body as Data
             request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")

            let config = URLSessionConfiguration.default
            self.session = URLSession(configuration: config, delegate: self, delegateQueue: self.opQueue)
            let fileUrl = URL(string:"\(videoPath)/\(fileName)")

            if let task = session?.uploadTask(with: request as URLRequest, from: video_data! as Data){
                task.resume()}
        }

        private func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            // the task finished
            if let err = error {
                print("Error: \(err.localizedDescription)")
            } else {
                print("The upload was successful.")
                self.session?.finishTasksAndInvalidate()
            }  // end if
        }  // end func

        private func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
            print("did receive response")
            self.response = response
            print(self.response!)
            completionHandler(URLSession.ResponseDisposition.allow)
        }  // end func

        private func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
            let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
            print(progress)
        }  // end func


        public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
            completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
        }

        func generateBoundaryString() -> String
        {
            return "Boundary-\(UUID().uuidString)"
        }
    }
}

Thanks in advance

ΩlostA
  • 2,501
  • 5
  • 27
  • 63
  • Is the the delegate pointer to `self` getting set to `nil` at some point in your application? – Aaron Dec 10 '18 at 16:56
  • Unrelated but don't use `NSMutable..` classes in Swift. Use `var request = URLRequest()` and create `body` as `var body = Data()` and append `body += Data("--\(boundary)\r\n".utf8)`. This particular `Data` initializer returns always a non-optional. – vadian Dec 10 '18 at 16:58
  • @Aaron Self is not nil for info – ΩlostA Dec 10 '18 at 17:46

1 Answers1

1

Remove the open parameter from your class: https://stackoverflow.com/a/38950955

In short: (from the other post)

An open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.
A public class is accessible but not subclassable outside of the defining module. A public class member is accessible but not overridable outside of the defining module.
dt dino
  • 1,194
  • 6
  • 19
  • Wow, it works, all the delegate functions are triggered. Very strange, I believed that open means open... – ΩlostA Dec 11 '18 at 14:26