Datastore API for iOS documentation

Datastores are an easy way to keep an app's per-user data — like settings, bookmarks, or game state — in sync across multiple devices and operating systems. Datastores are simple embedded databases, which are synced to Dropbox.

This reference details the full set of classes needed when working with datastores. You can also read the Datastore API tutorial for a detailed example of how to use them.

Dropbox apps can work with both datastores and files at the same time and this SDK includes functionality to handle both. For more information on the classes needed to work with files, see the Sync API documentation.

General information

All classes and methods in the API are thread-safe. Changes made to a datastore are atomic and are immediately visible to other threads accessing the same datastore. Calling -sync: persists datastore changes made by any thread to disk, queuing those changes for upload in the background, and also applying remote changes that have been downloaded.

Storage size limits

Datastores have limits on their maximum size to ensure good performance across platforms. You should keep these in mind as guidelines when modeling your datastores.

The overall size of a datastore is calculated by summing the sizes of all values of all fields, plus 1000 bytes for the datastore itself. Your app can store up to 5MB of data across all its datastores without counting against the user's storage quota. Any data beyond the first 5MB is factored into the user's Dropbox storage quota, and writing can be limited in these cases when a user is over quota.


The account manager is responsible for linking new users and persisting account information across runs of your app. You typically create an account manager at app startup with your app key and secret and keep it until your app terminates.

Class methods
  • + (void)setSharedManager:(DBAccountManager *)sharedManager

    A convenient place to store your app’s account manager.

  • + (DBAccountManager *)sharedManager

    A convenient place to get your app’s account manager.

  • @property (nonatomic, readonly) DBAccount *linkedAccount

    The currently linked account, or nil if there are no accounts currently linked.

    If your app needs to link multiple accounts at the same time, you should always use the linkedAccounts property.

  • @property (nonatomic, readonly) NSArray *linkedAccounts

    All currently linked accounts, or nil if there are no accounts currently linked.

    The accounts are ordered from the least recently to the most recently linked.

Instance methods
  • - (id)initWithAppKey:(NSString *)key secret:(NSString *)secret

    Create a new account manager with your app’s app key and secret. You can register your app or find your key at the apps page.

  • - (void)linkFromController:(UIViewController *)rootController

    This method begins the process for linking new accounts.



    the topmost view controller in your controller hierarchy.

  • - (DBAccount *)handleOpenURL:(NSURL *)url

    You must call this method in your app delegate’s -application:openURL:sourceApplication:annotation: method in order to complete the link process.


    The account object if the link was successful, or nil if the user cancelled.

  • - (void)addObserver:(id)observer block:(DBAccountManagerObserver)block

    Add block as an observer to get called whenever a new account is linked or an existing account is unlinked. The observer will be called regardless of whether the account was unlinked using -[DBAccount unlink] or by the user on the Dropbox website.



    this is only used as a handle to unregister blocks with the removeObserver: method.

  • - (void)removeObserver:(id)observer

    Use this method to remove all blocks associated with observer.



    the same value you provided to the addObserver:block: method.

  • typedef void (^DBObserver)()

    A generic block type used for observing changes throughout the Sync API

  • typedef void (^DBAccountManagerObserver)(DBAccount *account)

    An observer for the linkedAccount property


The account represents a particular user who has linked his account to your app. You can get account objects from the account manager.

  • @property (nonatomic, readonly) NSString *userId

    The user id of the account. This can be used to associate metadata with a given account.

  • @property (nonatomic, readonly, getter=isLinked) BOOL linked

    Whether the account is currently linked. Note that accounts can be unlinked via the unlink method or from the Dropbox website.

  • @property (nonatomic, readonly) DBAccountInfo *info

    Information about the user of this account, or nil if no info is available. Account info is fetched in the background. To be notified when account info is available or updated, use addObserver:block:.

Instance methods
  • This method unlinks a user’s account from your app.

    Once an account is unlinked, the local cache is deleted. If there is a filesystem object created with this account it will stop running.

  • - (void)addObserver:(id)observer block:(DBObserver)block

    Add block as an observer of an account to get notified whenever the account’s linked or info properties change.

  • - (void)removeObserver:(id)observer

    Remove all blocks associated with observer by the addObserver:block: method.


Information about a user’s account.

  • @property (nonatomic, readonly) NSString *displayName

    The recommended string to display to identify an account.

    This is “userName” if orgName is nil, otherwise it’s “userName (orgName)”.

  • @property (nonatomic, readonly) NSString *userName

    The user’s name.

  • @property (nonatomic, readonly) NSString *orgName

    The user’s organization’s name if available, or nil otherwise.


The DBError class is a subclass of NSError that always has domain set to DBErrorDomain.

Any method that can potentially fail will return a DBError object via the last parameter. Additionally, errors that happen in the background via syncing can also be retrieved, such as the error property on DBFileStatus.

Instance methods
  • - (DBErrorCode)code

    The code on a DBError object is always listed in the DBErrorCode enum.

  • typedef enum DBErrorCode

    The type of error that occurred. It will be one of the following:

    DBErrorUnknownHey, we don't know either
    DBErrorCoreSystemSystem error, out of memory, etc
    DBErrorParamsAn error due to data passed into the API
    DBErrorParamsInvalidA parameter is invalid, such as a nil object
    DBErrorParamsNotFoundA file corresponding to a provided paths was not found
    DBErrorParamsExistsYou tried to create a file that already exists
    DBErrorParamsAlreadyOpenFile was already open
    DBErrorParamsParentParent folder does not exist or is not a folder
    DBErrorParamsNotEmptyDirectory is not empty
    DBErrorParamsNotCachedFile was not yet in cache
    DBErrorParamsDisallowedApp is not allowed to perform this operation
    DBErrorParamsNoThumbNo thumbnail is available
    DBErrorParamsIndexIndex is out of bounds
    DBErrorParamsTypeValue is of the wrong type
    DBErrorSystemAn error in the library occurred
    DBErrorSystemDiskSpaceAn error happened due to insufficient local disk space
    DBErrorNetworkAn error occurred making a network request
    DBErrorNetworkTimeoutA connection timed out
    DBErrorNetworkNoConnectionNo network connection available
    DBErrorNetworkSSLUnable to verify the server's SSL certificate. Often caused by an out-of-date clock
    DBErrorNetworkServerUnexpected server error
    DBErrorNetworkQuotaThe user's Dropbox space is full
    DBErrorAuthAn authentication related problem occurred
    DBErrorAuthUnlinkedThe user is no longer linked
    DBErrorAuthInvalidAppAn invalid app key or secret was provided


The datastore manager lets you list, create, open, and delete datastores. You can also add an observer to find out when the list of datastores changes.

Class methods
  • + (DBDatastoreManager *)managerForAccount:(DBAccount *)account

    Gets the datastore manager for an account that has been linked via the account manager.

    The returned object will be the only datastore manager for this account until you release it, call shutDown, or the account is unlinked. Calling this method again in the mean time will return the same object.

  • @property (nonatomic, readonly, getter=isShutDown) BOOL shutDown

    Whether the datastore manager is currently shut down.

Instance methods
  • - (DBDatastore *)openDefaultDatastore:(DBError **)error

    Opens the default datastore for this account, or creates it if it doesn’t exist.


    The default datastore if successful, or nil if an error occurred.

  • - (NSArray *)listDatastores:(DBError **)error

    Lists the DBDatastoreInfo for each of the user’s datastores, including the default datastore if it has been created.


    A list of datastore DBDatastoreInfo objects if successful, or nil if an error occurred.

  • - (DBDatastore *)openDatastore:(NSString *)datastoreId error:(DBError **)error

    Open an existing datastore by its ID.

    The same datastore can’t be opened more than once.


    The datastore with the given ID if successful, or nil if an error occurred.

  • - (DBDatastore *)createDatastore:(DBError **)error

    Creates and opens a new datastore with a unique ID.


    The newly created datastore, or nil if an error occcurred.

  • - (BOOL)deleteDatastore:(NSString *)datastoreId error:(DBError **)error

    Deletes a datastore with the given ID.

    You must close open datastores before deleting them. The default datastore can never be deleted.


    YES if the datastore was deleted, or NO if an error occurrred.

  • - (void)addObserver:(id)obj block:(DBObserver)block

    Add a block to be called when a datastore is added or removed.

    Observers will always be called in the main thread.

  • - (void)removeObserver:(id)obj

    Remove all blocks associated with the given observer.

  • - (void)shutDown

    Shuts down the datastore manager, which stops all syncing.

    All associated DBDatastores will be closed. Unsynced changes to unclosed datastores will be lost. Changes that were synced before shutdown but not yet uploaded will be uploaded the next time that particular datastore is opened.

    After this call, the DBDatastoreManager and its DBDatastores can no longer be used. You should get a new DBDatastoreManager via managerForAccount:.

    The datastore manager will be automatically shut down if the app is unlinked remotely.


A datastore is a simple, syncable database for app data. You can open the default datastore using openDefaultStoreForAccount:error: and open or create other datastores using a DBDatastoreManager.

Class methods
  • + (DBDatastore *)openDefaultStoreForAccount:(DBAccount *)account error:(DBError **)error

    Opens the default datastore for this account.

  • @property (nonatomic, readonly, getter=isOpen) BOOL open

    Whether the datastore is currently open.

  • @property (nonatomic, readonly) DBDatastoreStatus status

    The current sync status of the datastore.

  • @property (nonatomic, readonly) NSString *datastoreId

    The ID for this datastore.

  • @property (nonatomic, readonly) DBDatastoreManager *manager

    The datastore manager for this datastore.

Instance methods
  • - (void)close

    Close a datastore when you’re done using it to indicate that you are no longer interested in receiving updates for this datastore.

    Any changes made since the last call to sync: will be discarded on close. If the account is unlinked remotely, the datastore will close automatically.

  • - (NSArray *)getTables:(DBError **)error

    Get all the tables in this datastore that contain records.

  • - (DBTable *)getTable:(NSString *)tableId

    Get a table with the specified ID, which can be used to insert or query records. If this is a new table ID, the table will not be visible until a record is inserted.

  • - (NSDictionary *)sync:(DBError **)error

    Apply all outstanding changes to the datastore, and also incorporate remote changes in.


    A dictionary mapping of tableId to a set of DBRecord objects if the call was successful, or nil if an error occurred. The table IDs and records in the dictionary correspond to the tables and records that changed due to remote changes applied during this sync. If records are deleted by the sync, the DBRecords will have the deleted property set, but no fields.

  • - (void)addObserver:(id)observer block:(DBObserver)block

    Add block as an observer when the status of the datastore changes.

  • - (void)removeObserver:(id)observer

    Remove all blocks registered for the given observer.

  • typedef NSUInteger DBDatastoreStatus

    A bitset indicating the current sync status of the datastore.

    The possible values set are:

    DBDatastoreConnectedThe API is connected with the server
    DBDatastoreDownloadingChanges are currently downloading
    DBDatastoreUploadingChanges are currently uploading
    DBDatastoreIncomingThere are remote changes waiting to be synced
    DBDatastoreOutgoingThere are local changes waiting to be synced


The datastore info class contains basic information about a datastore. Currently this only includes its ID, but more fields will be added in future.

  • @property (nonatomic, readonly) NSString *datastoreId

    The ID for this datastore.


A collection of records that lets you query for existing records or insert new ones. You can get an instance using the getTable: or getTables: methods on DBDatastore.

In addition to querying and inserting records, you can also set custom conflict resolution rules.

When using the max and min resolution rules, values are compared as follows: integer, floating point, boolean, and date values are ordered by their numerical value. String, byte, and list values are lexicographically ordered. Integer and floating point values are compared to each other by casting to double, but boolean values are treated as a distinct type ordered before all other numbers. Other values of distinct types are ordered by type, in the order listed above. For example, all boolean values are ordered before all other numeric values, which in turn are ordered before all string values.

Class methods
  • + (BOOL)isValidId:(NSString *)tableId

    Returns YES if tableId is a valid ID for a DBTable, or NO otherwise. IDs are case-sensitive, can be 1-32 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = IDs with a leading : are valid, but reserved for internal use.

  • @property (nonatomic, readonly) NSString *tableId

    The ID of the table.

  • @property (nonatomic, readonly) DBDatastore *datastore

    The datastore that contains this table.

Instance methods
  • - (NSArray *)query:(NSDictionary *)filter error:(DBError **)error

    Returns records matching the provided filter, or all records if filter is nil.



    For every key value pair in filter, the query will only return records where the field with the same name has the same value.

  • - (DBRecord *)getRecord:(NSString *)recordId error:(DBError **)error

    Returns a record with the given recordId, or nil if that record doesn’t exist or an error occurred.

  • - (DBRecord *)getOrInsertRecord:(NSString *)recordId fields:(NSDictionary *)fields inserted:(BOOL *)inserted error:(DBError **)error

    Returns a record with the given recordId (unmodified), or inserts a new record with the initial set of fields if it doesn’t exist already.



    if provided, the BOOL pointed to by inserted will be set to YES if a new record was inserted, or NO otherwise.


    the record if it is present in the table or inserted, or nil if an error occurred.

  • - (DBRecord *)insert:(NSDictionary *)fields

    Insert a new record with the initial set of fields into this table with a unique record ID.

  • - (void)setResolutionRule:(DBResolutionRule)rule forField:(NSString *)field

    Sets pattern as the resolution pattern for conflicts involving the given fieldname. The new resolution rule will be applied when merging local changes with remote changes during a call to -[DBDatastore sync:].

  • typedef enum DBResolutionRule

    Enum to specify how conflicts are resolved on a field

    DBResolutionRemoteResolves conflicts by always taking the remote change. This is the default resolution strategy.
    DBResolutionLocalResolves conflicts by always taking the local change.
    DBResolutionMaxResolves conflicts by taking the largest value, based on type-specific ordering (see DBRecord for more information).
    DBResolutionMinResolves conflicts by taking the smallest value, based on type-specific ordering (see DBRecord for more information).
    DBResolutionSumResolves conflicts by preserving additions or subtractions to a numeritcal value, which allows you to treat it as a counter or accumulator without losing updates. For non-numerical values this rule behaves as DBResolutionRemote.


A record represents an entry in a particular table and datastore. A record has a unique ID, and contains a set of fields, each of which has a name and a value. You can get records from a DBTable object.

Fields can hold values of the following types: NSNumber, NSString, NSData, NSDate, NSArray. For objects of type NSNumber, the value of objCType is not guaranteed to be preserved, but the datastore will distinguish been boolean, integer, and floating-point values. When you get a field that has a list value, its type will be DBList, which allows you to perform conflict-free list mutations.

Changes to this record are immediately visible to other record objects with the same tableId and recordId Calling -[DBDatastore sync:], which incorporates remote changes into your datastore, will also update any records you have a reference to.

Class methods
  • + (BOOL)isValidId:(NSString *)recordId

    Returns YES if recordId is a valid ID for a DBRecord, or NO otherwise. IDs are case-sensitive, can be 1-32 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = IDs with a leading : are valid, but reserved for internal use.

  • + (BOOL)isValidFieldName:(NSString *)name

    Returns YES if name is a valid name for a field in a DBRecord, or NO otherwise. Names are case-sensitive, can be 1-32 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = Names with a leading : are valid, but reserved for internal use.

  • @property (nonatomic, readonly) NSString *recordId

    The id of the record.

  • @property (nonatomic, readonly) DBTable *table

    The table that contains this record.

  • @property (nonatomic, readonly) NSDictionary *fields

    The fields of this record.

  • @property (nonatomic, readonly, getter=isDeleted) BOOL deleted

    Whether this record is deleted. A deleted DBRecord can’t be used to read or write fields.

Instance methods
  • - (id)objectForKey:(NSString *)key

    Get the value of a single field.

  • - (DBList *)getOrCreateList:(NSString *)fieldName

    Returns the current list at the given field, or returns an empty list if no value is set. If the field has a non-list value, this method will return nil.

    Please note that if the empty list is returned, the list won’t appear in the record until you insert an element. If you don’t insert any elements, the field will remain unset.

  • - (void)update:(NSDictionary *)fieldsToUpdate

    Update all the fields in the provided dictionary with the values that they map to.

  • - (void)setObject:(id)obj forKey:(NSString *)fieldName

    Update a single field with the provided value. The value must be non-nil.

  • - (void)removeObjectForKey:(NSString *)fieldName

    Remove a single field from the record.

  • - (void)deleteRecord

    Delete this record. This method has no effect on records which have already been deleted.


An object that allows you to modify a list that is set as a value on a record. Lists can contain the same values as records, except for other lists. Any changes you make to the list are intelligently merged with changes made remotely.

  • @property (nonatomic, readonly) NSArray *values

    Returns all objects in the list.

Instance methods
  • - (NSUInteger)count

    Returns the total number of items in the list.

  • - (id)objectAtIndex:(NSUInteger)index

    Returns the object at the given index.

  • - (void)insertObject:(id)obj atIndex:(NSUInteger)index

    Inserts an object at the given index, moving other objects further down the list.

  • - (void)removeObjectAtIndex:(NSUInteger)index

    Removes the object at the given index.

  • - (void)addObject:(id)obj

    Adds an object to the end of the list.

  • - (void)removeLastObject

    Removes the last object from the list.

  • - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)obj

    Replaces the item at the given index with the given object.

  • - (void)moveObjectAtIndex:(NSUInteger)oldIndex toIndex:(NSUInteger)newIndex

    Moves the object from the given old index, so that it appears at the given new index.