cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

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

RTS S.
Helpful | Level 6

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. 

5 Replies 5

Greg-DB
Dropbox 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.
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
Dropbox 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.
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
Dropbox 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.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Greg-DB Dropbox Staff
  • User avatar
    RTS S. Helpful | Level 6
What do Dropbox user levels mean?