Datastore API for OS X 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

Local datastores

This feature allows you to create local datastores without a linked Dropbox account, so you can use Datastores without requiring the user to log in with Dropbox. Local datastores are stored on the local device, and not synced to Dropbox. You can later migrate these datastores to a Dropbox account when the user chooses to link. If a user uses your app on multiple devices in local datastores mode and later links a Dropbox account, their data will be merged together once those devices link.

Local datastores are stored in a compressed delta format which allows their contents to be merged properly without taking up extra space on the device. A compressed delta is a minimal set of changes which have the same effect as the operations your app performed on a datastore. For instance, if you set the same field multiple times, there is no need to keep all values. The one exception is modifications to a list (through DBList), since list operations will not be compressed.

Shared datastores

Apps may want to share data between users. With the Datastore API, apps can share a datastore across multiple Dropbox accounts. The unit of sharing is a single datastore, and one or more datastores may be shared between accounts. Any datastore with a shareable ID (see "Private or shareable datastores" below) can be shared by assigning roles to principals, creating an access control list. Any Dropbox account with the correct permissions will then be able to open the shared datastore by ID.

There are two available principals to whom you may apply a role:

  • DBPrincipalPublic – The role will apply to all Dropbox users.
  • DBPrincipalTeam – The role will apply to everyone on the user's team (only applicable for Dropbox for Business accounts).

There are four available roles:

  • DBRoleNone – The principal has no access to this datastore.
  • DBRoleViewer – The principal is able to view this datastore.
  • DBRoleEditor – The principal is able to edit this datastore.
  • DBRoleOwner – The principal is the owner of this datastore. This role cannot be assigned directly. The user who created a datastore is always that datastore's owner.

Note that if your app is using local datastores, you can create a shareable datastore and update the permissions locally. However, the datastore can't actually be shared with others until after the user links their account to Dropbox and the data is migrated.

An example of sharing a datastore is included in the Datastore API tutorial.

Private or shareable datastores

Datastores can be created in 2 different ways, and the choice affects how they can be used. Each type of datastore can be identified by its ID.

  • Datastores with private IDs are created using DBDatastoreManager.openOrCreateDatastore:error:. Private IDs are meaningful to the developer of the app, such as "default" (for the default datastore) or "settings". The scope of private IDs is the current user-app pair. Two different devices can create datastores with the same private ID while offline, and their data will be merged when they come online.

    Private datastore IDs can be 1-64 characters containing only lowercase letters, digits, dot, hyphen or underscore, and they must not begin or end with dot.

  • Datastores with shareable IDs are created using DBDatastoreManager.createDatastore: which allows them to be shared between users. Their IDs are auto-generated and are not only unique for the user-app pair, they're also unique across Dropbox. Shareable IDs are more appropriate when treating each datastore as an individual document where users may create an unknown number of them.

    Shareable datastore IDs (generated by the SDK) are a dot followed by 1-63 characters containing uppercase letters, lowercase letters, hyphen or underscore.

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.

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. Sizes are calculated as:

  • The size of a datastore is calculated by summing the size of all records, plus 1000 bytes for the datastore itself.
  • The size of a record is calculated by summing the size of all values in all fields, plus 100 bytes for the record itself.
  • The size of a field is a fixed 100 bytes for the field itself plus:
    • for string or bytes values, the length in bytes of the value.
    • for List values, 20 bytes for each list element plus the size of each element.
    • for all other types, no additional contribution.
  • The size of changes made in a -sync: call is calculated by summing the size of each change, plus 100 bytes for the delta itself. The size of each change is calculated by summing the size of the values contained in the change (for field updates and list put and insert operations) plus 100 bytes for the change itself.

Thread safety

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. If your app uses multiple processes, you must make use of the Datastore API in only a single process, to avoid conflicting access to the cache on disk.

DBAccountManager

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.

Properties
  • @property (nonatomic, readonly) DBAccount *linkedAccount

    The most recently 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 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)linkFromWindow:(NSWindow *)parentWindow withCompletionBlock:(DBLinkCompletionBlock)block

    This method begins the process for linking new accounts.

    This will open the auth flow in a sheet. If parentWindow is nil it will open in a new window. When the user exits the flow, block will be called with the linked account which might be nil if the user cancelled or if there were errors.

    Your app can call this method repeatedly to link more than one account (such as personal and a business account).

    Parameters

    parentWindow

    the parent window the auth flow modal should be attached to.

    block

    the block that gets called when the user is done linking.

  • - (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.

    Parameters

    observer

    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.

    Parameters

    observer

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

Constants
  • 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

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

    A completion block called after linking with linkFromWindow:withCompletionBlock:

DBAccount

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

Properties
  • @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.

DBAccountInfo

Information about a user’s account.

Properties
  • @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.

DBError

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

Any method expected to 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.

Some failures (those which represent bugs or internal errors) will instead raise a DBException when they occur in an API method. A DBError will still be used if such a failure occurs on a background thread.

Instance methods
  • - (DBErrorCode)dbErrorCode

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

Constants
  • typedef enum DBErrorCode

    The type of error that occurred. It will be one of the following codes. Note that those codes marked as "Fatal" will generally cause exceptions rather than being returned as DBError. However you may see those codes in background sync status.

    DBErrorInternalInternal error or assertion in the SDK (Fatal)
    DBErrorCacheFailure accessing local cached data (Fatal)
    DBErrorShutdownAttempt to use an object or send a request after shutdown (Fatal)
    DBErrorClosedUse of an object which has been closed. (Fatal)
    DBErrorDeletedUse of an object which has been deleted. Used for synchronous local state transitions, not remote deletion (see DBErrorNotFound) (Fatal)
    DBErrorBadTypeAttempt to access a value of the wrong type (Fatal)
    DBErrorSizeLimitExceeding a fixed limit, such as maximum Datastore size. Not used for account quota which is subject to change (see DBErrorQuota). (Fatal)
    DBErrorBadIndexBad index into a list (Fatal)
    DBErrorIllegalArgumentIllegal argument to an API method (Fatal)
    DBErrorBadKeyBad key in an internal map lookup (Fatal)
    DBErrorBadStateAn object is in a bad state for an attempted operation (Fatal)
    DBErrorMemoryOut of memory (Fatal)
    DBErrorSystemError for the OS, when accessing private files or other OS resources (Fatal)
    DBErrorNotCachedUnable to read a file because it is unavailable in the cache (Fatal)
    DBErrorInvalidOperationAttempt to perform an illegal operation, such as opening a directory, or deleting the root
    DBErrorNotFoundFile, folder, or datastore does not exist
    DBErrorExistsOperation failed because the target already exists
    DBErrorAlreadyOpenAttempt to open a file or datastore which is already open
    DBErrorParentParent directories are missing or not directories
    DBErrorDiskSpaceOut of disk space for file storage. Applies to local disk space, not Dropbox quota (see DBErrorQuota)
    DBErrorDisallowedThe app attempted an operation that isn't allowed by its access level, or that the user does not have permission to perform
    DBErrorFileIOAn error accessing a file (outside of the SDK's cache)
    DBErrorCancelledAn operation was cancelled
    DBErrorReadOnlyAn operation try to act on a read-only file or folder
    DBErrorNetworkAn error occurred making a network request
    DBErrorTimeoutA connection timed out
    DBErrorNoConnectionNo network connection available
    DBErrorSSLFailure in SSL security or unable to verify the server's SSL certificate. Often caused by an out-of-date clock
    DBErrorServerThe server reported an error
    DBErrorAuthThe user has not authorized this app, or has unlinked this app
    DBErrorQuotaThe user's Dropbox space is full
    DBErrorRequestServer indicated that a request is invalid
    DBErrorResponseThe server returned an invalid response
    DBErrorRetryLaterThe client should wait a while and then repeat the request
    DBErrorParamsNoThumbNo thumbnail is available

DBException

The DBException class is a subclass of NSException that always has name set to DBExceptionName. A DBException is raised by a failure in an API method which indicates programming errors or internal SDK problems.

You should generally not have to catch a DBException, but the error property will allow you to classify or translate one if you need to.

Properties
  • @property (nonatomic, readonly) DBError *error

    Information about the error which caused this exception to be raised.

DBDatastoreManager

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.

  • + (DBDatastoreManager *)localManagerForAccountManager:(DBAccountManager *)accountManager

    Gets the local datastore manager for the accountManager.

  • + (DBDatastoreManager *)sharedManager

    A convenient place to get your app’s datastore manager. You must set it with setSharedManager first.

  • + (void)setSharedManager:(DBDatastoreManager *)manager

    Set your app’s datastore manager using this method. Retrieve it any time with sharedManager.

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

    Whether the datastore manager is currently shut down.

  • @property (nonatomic, readonly) DBAccount *account

    The account object this manager was created with. Will be nil if this is the local manager.

  • @property (nonatomic, readonly) BOOL isLocal

    Whether this is the local manager.

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

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

    Returns

    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.

    Returns

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

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

    Gets a map of ID to the DBDatastoreInfo for each of the user’s datastores, including the default datastore if it has been created. This method returns the most recent information from the server, but is overridden with the local version any time a local datastore has been changed and -[DBDatastore sync:] has been called (i.e. the changes have not yet been uploaded to the server).

    Returns

    A map of ID to the datastore DBDatastoreInfo objects if successful, or nil if an error occurred.

  • - (DBDatastoreManager *)migrateToAccount:(DBAccount *)account error:(DBError **)error

    Returns a new DBDatastoreManager created by migrating a local DBDatastoreManager to the given account.

    This will move all datastores and data from the local DBDatastoreManager to the new DBDatastoreManager. The new manager will immediately begin uploading to the server, and merging with any existing changes on the server

    The data is moved not copied, so the local datastore manager will be empty after migration. Migration should be done to a freshly linked account which contains no unuploaded datastore changes. If that isn’t the case, any datastore changes in the target account which will be overwritten by the migrated data.

    This must be called on a local DBDatastoreManager, and all of its datastores must be closed. If the account provided ever had a DBDatastoreManager it must be shut down. After this call, the current local DBDatastoreManager will be shut down and emptied.

    Returns

    The new datastore manager linked to the account, 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.

    Returns

    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.

    Returns

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

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

    Opens the datastore with the given ID, creating it if it does not already exist.

    Datastores can be created offline with this method, and their contents will be merged with any datastore of the same name when the app is online again.

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

    Call -[DBDatastore isValidId:] to check input strings before using them as a datastore ID.

    Returns

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

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

    Deletes a datastore with the given ID.

    You must close open datastores before deleting them.

    Returns

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

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

    Removes a datastore from the local cache.

    You must close open datastores before uncaching them.

    Any changes not yet uploaded to the server are discarded on uncache. If the datastore has such changes its DBDatastoreStatus has its incoming property set to YES. The next time a datastore is opened its entire snapshot is downloaded from the server.

    Returns

    YES if the datastore was uncached, or NO if an error occurred.

  • - (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.

DBDatastore

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.

You interact with data in the datastore using tables. You can call getTable: to get a table, or getTables: to list all tables in a datastore containing records.

Changes you make to the datastore will be visible immediately, and calling sync: will persist outgoing changes and queue them to be uploaded to the server. While a datastore is open, it will monitor for remote changes and download them when possible. When there are remote changes waiting to be incorporated, the DBDatastoreStatus will have its incoming property set to YES, and calling sync: will also apply those changes to your view of the datastore, resolving any conflicts along the way.

To find out when there are changes ready to be synced, add an observer using addObserver:block: to register a block that will be called every time status changes.

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

    Returns YES if datastoreId is a valid ID for a DBDatastore, or NO otherwise. Datastore IDs come in 2 forms:

    Private datastores (such as the default datastore) use IDs which can be 1-64 characters long, must not begin or end with a ‘.’, and may contain lower-case letters, digits, and these punctuation characters: . – _ (Note that older SDKs limited these to 32 characters, so take care if your datastore needs to be accessed by legacy clients.)

    Shareable datastore IDs (generated by `–[DBDatastoreManager createDatastore:]) always begin with a ‘.’ and can contain 1-63 additional characters which can be upper-case, lower-case, digits, and these punctuation characters: . –

  • + (BOOL)isValidShareableId:(NSString *)datastoreId

    Returns YES if datastoreId is a valid ID for a shareable DBDatastore, or NO otherwise. This is a valid ID (see isValidId) that starts with a ‘.’.

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

    Opens the default datastore for this account.

  • + (DBDatastore *)openDefaultLocalStoreForAccountManager:(DBAccountManager *)accountManager error:(DBError **)error

    Opens the local default datastore for this account manager.

Properties
  • @property (nonatomic, copy) NSString *title

    Set the title for this datastore. Will be nil if no title is set. Setting it to nil will delete the title field.

  • @property (nonatomic, readonly) NSDate *mtime

    The last modified time for this datastore, or nil if no data has been synced yet.

    The last modified time is automatically updated on each call to sync: which commits local changes, or incorporates remote changes. The timestamp is based on the local clock of the device where the change is made.

  • @property (nonatomic, readonly) NSUInteger size

    The current size of this datastore in bytes. The overall size of a datastore is calculated by summing the size of all records, plus the base size of an empty datastore itself.

  • @property (nonatomic, readonly) NSUInteger recordCount

    The total number of records in this datastore.

  • @property (nonatomic, readonly) NSUInteger unsyncedChangesSize

    The size in bytes of changes that will be queued for upload by the next call to sync:.

  • @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.

  • @property (nonatomic, readonly) DBRole effectiveRole

    The effective role the current user has for this datastore.

  • @property (nonatomic, readonly) BOOL isWritable

    Whether this datastore can be written (i.e., role is owner or editor).

  • @property (nonatomic, readonly) BOOL isShareable

    Whether this datastore can be shared.

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.

    Returns

    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.

  • - (DBRole)getRoleForPrincipal:(NSString *)principal

    Get the role specified by the ACL for a principal (shareable datastores only).

  • - (void)setRoleForPrincipal:(NSString *)principal to:(DBRole)role

    Assign a role to a principal in the ACL (shareable datastores only).

  • - (void)deleteRoleForPrincipal:(NSString *)principal

    Delete any role for a principal from the ACL(shareable datastores only).

  • - (NSDictionary *)listRoles

    Return the ACL in the form of a mapping from principals to roles (as NSIntegers).

Constants
  • NSUInteger DBDatastoreSizeLimit

    The maximum size in bytes of a datastore.

  • NSUInteger DBDatastoreUnsyncedChangesSizeLimit

    The maximum size in bytes of changes that can be queued up between calls to sync:.

  • NSUInteger DBDatastoreRecordCountLimit

    The maximum number of records in a datastore.

  • NSUInteger DBDatastoreBaseSize

    The size in bytes of a datastore before accounting for the size of its records.

    The overall size of a datastore is this value plus the size of all records.

  • NSUInteger DBDatastoreBaseUnsyncedChangesSize

    The size in bytes of unsynced changes before accounting for the size of each change.

    The overall size of unsynced changes is this value plus the size of each change.

  • NSUInteger DBDatastoreBaseChangeSize

    The size in bytes of a change before accounting for the size of its values.

    The overall size of a change is this value plus the size of the values in the change.

  • typedef enum DBRole

    Enum giving the possible roles a principal can have with respect to a DBDatastore.

    DBRoleNoneNo permission
    DBRoleViewerRead-only permission
    DBRoleEditorRead-write permission (includes ACL changes)
    DBRoleOwnerOwner (same as read-write, cannot be kicked out)
  • NSString * const DBPrincipalTeam

    The principal used to set or retrieve the role for Dropbox for Business team members.

  • NSString * const DBPrincipalPublic

    The principal used to set or retrieve the role for the general public.

DBDatastoreInfo

The datastore info class contains basic information about a datastore.

Properties
  • @property (nonatomic, readonly) NSString *datastoreId

    The ID for this datastore.

  • @property (nonatomic, readonly) NSString *title

    The title for this datastore, or nil if none is set.

  • @property (nonatomic, readonly) NSDate *mtime

    The last modified time for this datastore, or nil if none is set. The last modified time is automatically updated on each call to -[DBDatastore sync:] which commits local changes, or incorporates remote changes. The timestamp is based on the local clock of the device where the change is made.

  • @property (nonatomic, readonly) DBRole role

    The role the current user has for this datastore.

  • @property (nonatomic, readonly) BOOL isShareable

    Whether this datastore is shareable. (== whether datastoreId starts with ‘.’)

  • @property (nonatomic, readonly) BOOL isWritable

    Whether this datastore can be written (i.e., role is owner or editor).

DBDatastoreStatus

Sync status for a DBDatastore, including any errors that are preventing syncing.

Properties
  • @property (nonatomic, readonly) BOOL connected

    Whether the API is in active communication with the server so that remote changes are likely to be visible quickly, and local changes can be uploaded soon. The API will attempt to connect when datastores are open, but may fail if offline.

  • @property (nonatomic, readonly) BOOL downloading

    Whether there are remote changes that need to be downloaded from the server. Always set when a DBDatastore is opened until the first successful check for updates. Always set for a local datastore.

  • @property (nonatomic, readonly) BOOL uploading

    Whether there are local changes that need to be uploaded to the server. Always set for a local datastore that has any changes at all.

  • @property (nonatomic, readonly) BOOL incoming

    Whether there are remote changes that will be incorporated by the next call to -[DBDatastore sync:].

  • @property (nonatomic, readonly) BOOL outgoing

    Whether there are local changes that haven’t yet been committed by a call to -[DBDatastore sync:].

  • @property (nonatomic, readonly) BOOL needsReset

    Whether the local datastore needs to be reset with a call to -[DBDatastore close:] followed by -[DBDatastoreManager uncacheDatastore:].

  • @property (nonatomic, readonly) DBError *uploadError

    The latest error preventing local datastore state from being uploaded, or nil if there is no error

  • @property (nonatomic, readonly) DBError *downloadError

    The latest error preventing remote datastore state from being downloaded, or nil if there is no error

  • @property (nonatomic, readonly) DBError *anyError

    An error (downloadError or uploadError) affecting this datastore, or nil if there is no error. This is a convenience for determining whether any operations are failing.

DBTable

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-64 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = IDs with a leading : are valid, but reserved for internal use. (Note that older SDKs limited these to 32 characters, so take care if your datastore needs to be accessed by legacy clients.)

Properties
  • @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.

    Parameters

    filter

    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.

    Parameters

    inserted

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

    Returns

    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:].

Constants
  • 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.

DBRecord

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-64 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = IDs with a leading : are valid, but reserved for internal use. (Note that older SDKs limited these to 32 characters, so take care if your datastore needs to be accessed by legacy clients.)

  • + (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-64 characters long and may contain alphanumeric characters plus these punctuation characters: . – _ + / = Names with a leading : are valid, but reserved for internal use. (Note that older SDKs limited these to 32 characters, so take care if your datastore needs to be accessed by legacy clients.)

Properties
  • @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) NSUInteger size

    The size of this record in bytes. The size of a record is calculated by summing the size of all values in all fields, plus the base size of an empty record itself.

  • @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 raise an exception.

  • - (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.

Constants
  • NSUInteger DBRecordSizeLimit

    The maximum size in bytes of a record.

  • NSUInteger DBRecordBaseSize

    The size in bytes of a record before accounting for the size of its fields.

    The overall size of a record is this value plus the sum of the sizes of its fields.

  • NSUInteger DBFieldBaseSize

    The size in bytes of a field before accounting for the sizes of its values.

    The overall size of a field is this value plus

    NSString and NSData The length in bytes of the value.
    NSArray The sum of the size of each list item, where each item's size is computed as the size of the item value plus DBListItemBaseSize.
    Other types No additional contribution to the size of the field.

DBList

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.

Properties
  • @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.

Constants
  • NSUInteger DBListItemBaseSize

    The size in bytes of a list item before accounting for the size of its value.

    The overall size of a list item is this value plus the size of the object.