We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.

Forum Discussion

RTS S.'s avatar
RTS S.
Helpful | Level 6
10 years ago

Swift API v2 Example of uploading a file using filesUploadSession(Start, Append, Finish)

I have used the OSX interface in the past for chunked file uploads to support large files. I can not quite figure out the process with the Swift API. 

Test cases for the API would be great, they would provide examples of usage. 

In the absence ... do you have any code examples that you can share. 

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    I don't think we have a full sample using that published, but here's a very simple example I just put together: (apologies for the atrocious code formatting on the forum)

            // Write a file to the local documents directory
            let text = "Hello world. Usually something much longer here."
            let filename = "working-draft.txt"
            let localDir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
            let localPath = localDir.stringByAppendingString(filename)
            try! text.writeToFile(localPath, atomically:true, encoding:NSUTF8StringEncoding)
     
            let fileURL = NSURL.fileURLWithPath(localPath)
            let fileLength = UInt64(text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
            print(fileURL)
            print(fileLength)
     
            // start the upload session, passing along the NSURL to the whole file in this case, since it's small
            // there are also versions that take NSData or NSInputStream as the body
            client.filesUploadSessionStart(body: fileURL).response { response, error in
                if let result = response {
                    // the call succeeded
                    print(result)
                    
                    // also call filesUploadSessionAppend to add more data if/as necessary, as many times as necessary (be sure to track the offset)
                    
                    // we're ready to finish the upload and commit the file
                    client.filesUploadSessionFinish(cursor: Files.UploadSessionCursor(sessionId: result.sessionId, offset: fileLength),
                                                    commit: Files.CommitInfo(path: "/test_swift_upload_session.txt"),
                                                    // no additional data to add at this point in this case
                                                    body:NSData()).response { response, error in
                                                        if let result = response {
                                                            print(result)
                                                        } else {
                                                            print(error!)
                                                        }
                    }
                    
                } else {
                    // the call failed
                    print(error!)
                }
            }
  • RTS S.'s avatar
    RTS S.
    Helpful | Level 6

    If I try to load a 1GB files with a Stream input  using  filesUploadSessionStart  will the file get completely uploaded by the time it calls the response ? 

    If not how do I find how much was transferred so I know where to start with subsequent filesUploadSessionAppend ... that's the part I am missing.

     

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    Each call to filesUploadSessionStart, filesUploadSessionAppend, or filesUploadSessionFinish uploads all of the data you give to it. So in your case, if you supply 1 GB, it will attempt to upload all of that data at once, before response is called. That will likely fail though, so you should instead only upload a piece at a time. E.g., you could use chunks of 4 MB, where you supply 4 MB to start, another 4 MB to append repeatedly as necessary, and then the remainder to finish.

  • RTS S.'s avatar
    RTS S.
    Helpful | Level 6

    Is there a reason why filesUploadSessionAppend takes an offset and Session ID and filesUploadSessionFinish takes a Files.UploadSessionCursor which wraps the Offset and Session ID ?

    Seems like these calls should hava a similar calling convention except that SessionFinsish should have the extra  CommitInfo

     

    Actually I think the API would be cleaner with a smple

       SessionStart -- NO Data just return the SessonID

       SessionAppend   Args would be SessionID, Data, and Offset

       SessionFinish     Args would be SessionID and Completion

    Adding a data transfer to the SessionStart and SessionFinish makes the interface much more clunky ... and all you have saved is possibly one small packet transfer. You Currently need minimally 2 requests (Start and Finish), one can be small. With a cleaner interface you would need minimally 3 requests, two are small.

     

     

     

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    Thanks for the feedback! I don't know off hand why append and finish are different, but I'll be sure to pass this along.