cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to make sure we keep you updated on the ideas that other users have shared here on the Community? Us too! Check them out over 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: 
1
Ask
2
Reply and help

Uploading a file to Dropbox in chunks using Objective C

Uploading a file to Dropbox in chunks using Objective C

Bjorn1
Explorer | Level 3

This is maybe a very simple question, but I'm looking for an example how to upload a file to Dropbox using Objective C on iOS. For small files this is rather straightforward, but for large files it's more difficult. Is there any simple example on the web how to use: uploadSessionStart, uploadSessionAppendV2 and uploadSessionFinish?

 

Any ideas welcome!

1 Reply 1

Re: Uploading a file to Dropbox in chunks using Objective C

Greg-DB
Dropboxer

We don't have an example for using upload sessions in the API v2 Objective-C SDK unfortunately, but I'll pass this along as a request for one.

 

I have some samples for other languages though, which may still be useful, since the logic is the same.

 

For example, a simple implementation in Python:

f = open(file_path)
file_size = os.path.getsize(file_path)

CHUNK_SIZE = 8 * 1024 * 1024

if file_size <= CHUNK_SIZE:

    print dbx.files_upload(f.read(), dest_path)

else:

    upload_session_start_result = dbx.files_upload_session_start(f.read(CHUNK_SIZE))
    cursor = dropbox.files.UploadSessionCursor(session_id=upload_session_start_result.session_id,
                                               offset=f.tell())
    commit = dropbox.files.CommitInfo(path=dest_path)

    while f.tell() < file_size:
        if ((file_size - f.tell()) <= CHUNK_SIZE):
            print dbx.files_upload_session_finish(f.read(CHUNK_SIZE),
                                            cursor,
                                            commit)
        else:
            dbx.files_upload_session_append(f.read(CHUNK_SIZE),
                                            cursor.session_id,
                                            cursor.offset)
            cursor.offset = f.tell()

f.close()

Here's a longer example in Swift that splits out every error case:

 

import UIKit
import SwiftyDropbox

class ViewController: UIViewController {

    // filled in later in doUpload:
    var fileHandle : NSFileHandle? = nil
    var data : NSData? = nil

    let chunkSize = 8 * 1024 * 1024  // 8 MB
    var offset = 0
    var sessionId = ""

    // replace this with your desired destination path:
    let destPath = "/SwiftyDropbox_upload.txt"

    override func viewDidLoad() {
        super.viewDidLoad()

        Dropbox.authorizedClient = DropboxClient(...)

        doUpload()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func doUpload() {

        // replace this with the path to the file you want to upload
        let filePath = "/path/to/file"
        print("Getting file at \(filePath) for uploading...")
        fileHandle = NSFileHandle.init(forReadingAtPath: filePath)!

        print("Using chunked uploading with chunk size \(chunkSize)...")
        uploadFirstChunk()

    }

    func uploadFirstChunk() {
        data = fileHandle!.readDataOfLength(chunkSize)
        let size = data!.length
        print("Have \(size) bytes to upload.")
        Dropbox.authorizedClient!.files.uploadSessionStart(input:data!)
            .response { response, error in
                if let result = response {
                    self.sessionId = result.sessionId
                    self.offset += size
                    print("So far \(self.offset) bytes have been uploaded.")
                    self.uploadNextChunk()
                } else if let callError = error {
                    print("uploadSessionStart failed")
                    switch callError as CallError {
                    case .RouteError(let error, let requestId):
                        print("RouteError[\(requestId)]: \(error)")
                    case .BadInputError(let message, let requestId):
                        print("BadInputError[\(requestId)]: \(message)")
                    case .HTTPError(let code, let message, let requestId):
                        print("HTTPError[\(requestId)]: \(code): \(message)")
                    case .InternalServerError(let code, let message, let requestId):
                        print("InternalServerError[\(requestId)]: \(code): \(message)")
                    case .OSError(let err):
                        print("OSError: \(err)")
                    case .RateLimitError:
                        print("RateLimitError")
                    }
                }
        }
    }

    func uploadNextChunk() {
        data = fileHandle!.readDataOfLength(chunkSize)
        let size = data!.length
        print("Have \(size) bytes to upload.")
        if size < chunkSize {
            print("Last chunk!")
            Dropbox.authorizedClient!.files.uploadSessionFinish(
                cursor: Files.UploadSessionCursor(sessionId: self.sessionId, offset: UInt64(offset)),
                commit: Files.CommitInfo(path:destPath),
                input: data!)
                .response { response, error in
                    if let callError = error {
                        print("uploadSessionFinish failed")
                        switch callError as CallError {
                        case .RouteError(let boxed, let requestId):
                            print("RouteError[\(requestId)]:")
                            switch boxed.unboxed as Files.UploadSessionFinishError {
                            case .Path(let writeError):
                                print("Path: ")
                                switch writeError {
                                case .MalformedPath(let malformedPathError):
                                    print("MalformedPath: \(malformedPathError)")
                                case .Conflict(let writeConflictError):
                                    print("Conflict:")
                                    switch writeConflictError {
                                    case .File:
                                        print("File")
                                    case .FileAncestor:
                                        print("FileAncestor")
                                    case .Folder:
                                        print("Folder")
                                    case .Other:
                                        print("Other")
                                    }
                                case .DisallowedName:
                                    print("DisallowedName")
                                case .InsufficientSpace:
                                    print("InsufficientSpace")
                                case .NoWritePermission:
                                    print("NoWritePermission")
                                case .Other:
                                    print("Other")
                                }
                            case .LookupFailed(let uploadSessionLookupError):
                                print("LookupFailed:")
                                switch uploadSessionLookupError {
                                case .Closed:
                                    print("Closed")
                                case .IncorrectOffset(let uploadSessionOffsetError):
                                    print("IncorrectOffset: \(uploadSessionOffsetError)")
                                case .NotFound:
                                    print("NotFound")
                                case .NotClosed:
                                    print("NotFound")
                                case .Other:
                                    print("Other")
                                }
                            case .TooManySharedFolderTargets:
                                print("TooManySharedFolderTargets")
                            case .Other:
                                print("Other")
                            }
                        case .BadInputError(let message, let requestId):
                            print("BadInputError[\(requestId)]: \(message)")
                        case .HTTPError(let code, let message, let requestId):
                            print("HTTPError[\(requestId)]: \(code): \(message)")
                        case .InternalServerError(let code, let message, let requestId):
                            print("InternalServerError[\(requestId)]: \(code): \(message)")
                        case .OSError(let err):
                            print("OSError: \(err)")
                        case .RateLimitError:
                            print("RateLimitError")
                        }
                    } else if let result = response {
                        print("Done!")
                        print(result)
                    }
            }
        } else {
            Dropbox.authorizedClient!.files.uploadSessionAppendV2(
                cursor: Files.UploadSessionCursor(sessionId: self.sessionId, offset: UInt64(offset)),
                input: data!)
                .response { response, error in
                    if error == nil {
                        self.offset += self.chunkSize
                        print("So far \(self.offset) bytes have been uploaded.")
                        self.uploadNextChunk()
                    } else if let callError = error {
                        print("uploadSessionAppend failed")
                        switch callError as CallError {
                        case .RouteError(let boxed, let requestId):
                            print("RouteError[\(requestId)]:")
                            switch boxed.unboxed as Files.UploadSessionLookupError {
                            case .Closed:
                                print("Closed")
                            case .IncorrectOffset(let uploadSessionOffsetError):
                                print("IncorrectOffset: \(uploadSessionOffsetError)")
                            case .NotFound:
                                print("NotFound")
                            case .NotClosed:
                                print("NotClosed")
                            case .Other:
                                print("Other")
                            }
                        case .BadInputError(let message, let requestId):
                            print("BadInputError[\(requestId)]: \(message)")
                        case .HTTPError(let code, let message, let requestId):
                            print("HTTPError[\(requestId)]: \(code): \(message)")
                        case .InternalServerError(let code, let message, let requestId):
                            print("InternalServerError[\(requestId)]: \(code): \(message)")
                        case .OSError(let err):
                            print("OSError: \(err)")
                        case .RateLimitError:
                            print("RateLimitError")
                        }
                    }
            }
        }
    }

}

 

 

 

 

Who's talking

Top contributors to this post

  • User avatar
    Greg-DB Dropboxer
What do Dropbox user levels mean?
Need more support?