Mobile Application Development

Chapter 6
Local Data, Files and Offline-First Applications

Bachelors Program in IT
Mobile Application Development   •   Bachelor

Local Data, Files and Offline-First Applications

Introduction

Mobile applications operate in environments that are less predictable than desktop or server systems. A device may lose connectivity, enter power-saving mode, have limited storage, or be used while moving between networks. Users nevertheless expect an application to open quickly, preserve their work, and provide consistent information. These expectations make local data management a central concern in mobile application development rather than an optional optimization.

This chapter examines the main mechanisms used to store and manage data on mobile devices: preferences, files, relational databases, non-relational databases, caches, and synchronization services. It then develops the repository and offline-first patterns needed to combine these mechanisms into reliable applications. Particular attention is given to data integrity, schema migration, security, synchronization order, and conflict resolution.

An offline-first application treats local data as a primary source for user interaction. Network access improves freshness and enables synchronization, but the user interface does not fundamentally depend on a continuous connection. This approach differs from simply adding a cache to an online application: it requires explicit decisions about ownership, consistency, failure recovery, and the meaning of conflicting changes.

Learning Objectives

By the end of this chapter, you should be able to:

  1. Select an appropriate local-storage mechanism for different data types.
  2. Explain the roles of preferences, files, databases, and caches.
  3. Design repository interfaces that isolate user-interface code from storage and network details.
  4. Construct an offline-first workflow using local reads, an outbox, and synchronization.
  5. Apply transactions, constraints, migrations, and validation to protect data integrity.
  6. Compare conflict-resolution strategies and identify their limitations.
  7. Address security, privacy, testing, and governance issues in local data systems.

1. The Local Data Problem

A mobile application commonly handles several categories of information:

  • Configuration: theme, language, notification choices, and onboarding status.
  • User-generated records: notes, orders, tasks, messages, or health observations.
  • Large binary objects: photographs, videos, documents, and audio.
  • Derived information: search indexes, thumbnails, computed totals, and temporary results.
  • Remote copies: data obtained from a server and retained for later use.
  • Pending operations: changes made locally but not yet accepted by a server.

These categories have different durability, query, performance, and security requirements. A boolean preference does not need a relational schema, while thousands of orders require indexing and transaction support. A video should generally be stored as a file rather than inserted as a database text value. A cached response can be deleted and rebuilt; a user's unsent expense report cannot.

A useful design question is not simply “Where can this data be stored?” but “What is the required lifetime, authority, structure, and recovery behavior of this data?”

Important terminology

  • Durability: the probability that data remains after an application restart or device failure.
  • Volatile data: data that may be discarded without significant loss.
  • Source of truth: the component whose value is authoritative when alternatives disagree.
  • Cache: a replaceable copy retained to reduce latency, bandwidth, or computation.
  • Serialization: conversion of an in-memory object into a storable representation.
  • Deserialization: reconstruction of an in-memory object from stored data.
  • Idempotency: the property that repeating an operation produces the same effective result as performing it once.
  • Consistency: the degree to which observed data satisfies defined correctness rules.

2. Choosing a Storage Mechanism

Preferences and key-value storage

Preferences are appropriate for small values addressed by a key: a selected language, a last-viewed tab, or whether a tutorial has been completed. They are not appropriate for relational records, large media, passwords, or data requiring complex queries.

Preference values should be treated as untrusted input. A stored value can be missing, corrupted, written by an older application version, or changed by a user restoring a backup. Code should therefore provide defaults and validate values when reading them.

For sensitive values such as authentication tokens, use a platform-provided secure credential facility or encrypted storage. Ordinary preferences are usually not a suitable secret vault.

Files and directories

The file system is appropriate for documents and binary data. Applications should separate:

  • Documents or user-created files, which may need deliberate preservation or export.
  • Application support files, which are internal but durable.
  • Temporary files, which may be deleted at any time.
  • Cache files, which should be reproducible from another source.

Use atomic replacement when updating important files: write a new temporary file, flush and close it as appropriate, then replace the old file. This reduces the chance that a crash leaves a partially written document. File names should not be constructed directly from unvalidated user input, because path traversal and invalid characters can create security and reliability problems.

Large files should normally be streamed rather than loaded entirely into memory. Metadata such as file identifier, media type, size, checksum, and local path can be stored in a database while the binary content remains in the file system.

Relational databases

A relational database represents information in tables containing rows and columns. It is well suited to structured entities, relationships, constraints, joins, filtering, and transactions. A task system might contain Task, Project, and TaskTag tables, with foreign keys expressing relationships.

A relational design typically involves:

  1. Identifying entities and their attributes.
  2. Assigning stable primary keys.
  3. Representing relationships with foreign keys or junction tables.
  4. Adding constraints such as NOT NULL, uniqueness, and valid ranges.
  5. Creating indexes for common query predicates.
  6. Grouping related writes in transactions.

An index accelerates selected reads but consumes storage and makes writes more expensive. Indexes should therefore follow measured query patterns rather than being added indiscriminately.

Transactions provide an all-or-nothing unit of work. If creating an order requires inserting an order row and several line rows, a transaction prevents a crash from leaving only part of the order. Transaction guarantees depend on the database and platform, so developers must consult the relevant implementation documentation rather than assuming every storage API has identical behavior.

Non-relational databases

Non-relational, or NoSQL, stores include document, key-value, wide-column, and graph databases. A document store can represent an object as a nested document and may reduce mapping code for irregular data. A key-value store is useful when data is naturally retrieved by one key. A graph model is suitable when relationships are central to queries.

NoSQL does not mean “without structure.” Applications still require a documented schema, validation rules, versioning, and migration strategy. Denormalization may improve read performance but creates duplication: updating one fact may require updating several documents. The choice should be based on access patterns, transaction needs, query complexity, and platform support—not on the popularity of a technology.

Caches

A cache is disposable by design. It should have a clear invalidation policy, bounded size, and behavior for stale entries. Common policies include:

  • Cache-aside: the application reads the cache, fetches from the server on a miss, then stores the result.
  • Read-through: the storage abstraction fetches missing data automatically.
  • Write-through: a write updates the cache and its backing store together.
  • Time-to-live (TTL): an item is considered stale after a specified duration.
  • Least recently used (LRU): entries used least recently are removed when capacity is reached.

A cache must not silently become the only copy of irreplaceable user data. If its contents can be deleted without user-visible loss, it is a cache; otherwise it is persistent application data and should be designed accordingly.

Data requirementSuitable mechanismMain caution
Small settingsPreferences/key-value storeValidate defaults; do not store secrets casually
Photos and documentsFilesAtomic writes, permissions, storage limits
Related structured recordsRelational databaseSchema, indexes, migrations
Irregular aggregate objectsDocument databaseValidation and duplication
Replaceable remote resultsCacheInvalidation and staleness
Passwords or tokensSecure credential storeKey management and revocation

3. Data Modeling and Integrity

Data integrity means that stored information remains accurate, complete, and consistent with the application's rules. It is achieved through several layers:

  • Type integrity: values have valid representations and types.
  • Entity integrity: each record has a unique, stable identity.
  • Referential integrity: related records refer to existing records or explicitly allow absence.
  • Domain integrity: values satisfy business rules, such as a non-negative quantity.
  • Process integrity: multi-step changes cannot leave an invalid intermediate result.

Validation at the interface improves usability, but it is not sufficient. Data can enter through imports, synchronization, older versions, accessibility tools, or other code paths. Validation must also occur at the repository, database, and server boundaries where appropriate.

Identity and timestamps

A local record needs an identifier that remains stable across edits and synchronization. A randomly generated identifier, such as a UUID, can allow a device to create records offline without first obtaining a server-generated integer. Identifiers must not be treated as proof of authorization.

Timestamps require care. Device clocks can be wrong, changed, or in different time zones. Store instants in a consistent representation, commonly UTC, and display them in the user's locale. For ordering synchronization events, a server revision, logical sequence, or version token is often more reliable than a device wall-clock timestamp.

Transactions and atomicity

Suppose a note is edited and an outbox entry is created for later synchronization. If the note is saved but the outbox entry is not, the edit may never reach the server. If the outbox entry exists but the note does not, synchronization may transmit a nonexistent object. These writes should occur in one local transaction whenever the database supports it.

A transaction is especially important for maintaining invariants. An invariant is a condition that must remain true after every completed operation—for example, every outbox operation must refer to a locally known entity, or every child row must refer to an existing parent.

4. Schema Evolution and Migration

A schema migration changes the representation of stored data while preserving its meaning. It becomes necessary when an application adds a column, renames an entity, changes a data type, or restructures documents.

A robust migration process includes:

  1. Assigning a schema version.
  2. Defining the old and new schema precisely.
  3. Writing a deterministic migration.
  4. Testing migration on realistic old databases.
  5. Preserving data that has no direct new equivalent through a documented rule.
  6. Handling failure without destroying the original data.
  7. Testing upgrade, rollback limitations, and interrupted migration behavior.

For example, if a fullName field is divided into givenName and familyName, the migration may split on the first space, but this is not universally correct for all names. A better approach may preserve the original value, place it in a review field, or obtain explicit user confirmation. Migration is therefore a semantic operation, not merely a mechanical column alteration.

Destructive changes should be delayed until backups, export paths, or successful conversion have been established. In distributed applications, server and client versions may coexist, so APIs should often support more than one representation during a transition.

5. Repositories and Separation of Concerns

A repository is an abstraction that exposes application-level data operations without exposing whether data comes from a database, file, memory cache, or network. For example:

TaskRepository
  observeTasks(projectId)
  getTask(taskId)
  saveTask(task)
  deleteTask(taskId)
  synchronize()

The user interface should depend on this contract rather than issuing SQL queries or HTTP requests directly. A repository can coordinate a local data source, remote data source, cache, and synchronization queue.

A practical layered design is:

  1. Presentation layer: screens, view models, and user actions.
  2. Domain layer: use cases and business rules.
  3. Repository layer: application-facing data contracts.
  4. Data sources: local database, file store, preferences, and remote API.
  5. Platform services: connectivity, secure storage, background scheduling, and logging.

Repositories should not become untestable “god objects.” Separate concerns such as conflict resolution, serialization, and queue processing when their complexity grows. Interfaces should describe meaningful operations, not merely expose every database method.

6. The Offline-First Workflow

An offline-first workflow commonly follows this sequence:

  1. The user performs an action.
  2. The application validates it locally.
  3. The local database is updated immediately.
  4. A pending operation is added to an outbox in the same transaction.
  5. The interface observes local data and updates quickly.
  6. A synchronizer submits pending operations when connectivity is available.
  7. The server accepts, rejects, or transforms the operation.
  8. The client records the result, applies authoritative changes, and removes or retries the outbox item.

This is often called local-first mutation. It gives the user immediate feedback while making synchronization an explicit process.

User action
    ↓
Local validation ──invalid──> Explain error
    ↓ valid
Database transaction: update entity + append outbox operation
    ↓
UI observes local database
    ↓ connectivity
Synchronizer sends operation with identity and version
    ↓
Server: accept / reject / conflict
    ↓
Apply response, retry safely, or request resolution

Figure: A local-first mutation and synchronization workflow.

The outbox pattern

An outbox is a durable local queue of operations. A useful outbox record may contain:

  • operation identifier;
  • entity identifier and type;
  • operation kind, such as create, update, or delete;
  • serialized payload or patch;
  • base version observed when editing began;
  • attempt count and last-attempt time;
  • status and error information.

The operation identifier supports idempotency. If a request reaches the server but the response is lost, the client may retry. The server should recognize the same operation identifier and avoid applying the operation twice.

Retries should use bounded exponential backoff with jitter rather than immediate infinite repetition. Permanent errors, such as a validation failure, should be surfaced or placed in a recoverable error state. Authentication failures require reauthentication, not blind retries.

Pulling remote changes

Synchronization is bidirectional. A client must upload local operations and download changes made elsewhere. A server may provide a change feed, cursor, revision number, or synchronization token. The client stores the token only after successfully applying the corresponding batch; otherwise it may skip changes after a crash.

A safe synchronization cycle is usually:

  1. Acquire a synchronization lock.
  2. Upload eligible outbox operations.
  3. Process acknowledgements and conflicts.
  4. Request remote changes after the last confirmed cursor.
  5. Apply changes transactionally.
  6. Persist the new cursor.
  7. Release the lock and schedule another cycle if work remains.

The exact order depends on application semantics. For example, a messaging application may pull before pushing to reduce conflicts, whereas a task application may push local edits first. The policy must be explicit.

7. Consistency and Conflict Resolution

A conflict occurs when two actors modify the same logical data without a common final state. Connectivity loss alone is not a conflict; it becomes one when concurrent changes cannot both be applied under the application's rules.

Common strategies include:

Last-write-wins

The value with the latest selected timestamp or version replaces the other. This is simple but can silently discard a legitimate edit, and device clocks may be unreliable. If used, a server-assigned ordering is generally preferable to an untrusted client clock.

Version-based rejection

The client includes the version it edited. The server accepts the update only if the current version still equals that base version. Otherwise it returns a conflict. This prevents silent overwriting and is suitable for important records, although it requires a user or policy to merge changes.

Field-level or operation-level merge

Independent fields can sometimes be combined: one user changes a title while another changes a due date. Operation-based models may append independent actions rather than transmit complete replacement objects. Merging is safe only when the domain rules justify it; blindly merging fields can violate business invariants.

User-assisted resolution

The application displays both versions and lets the user choose or edit a result. This is appropriate for documents and high-value records, but it increases interface complexity and requires preservation of enough history to explain the conflict.

Tombstones and deletion

A deletion must be represented during synchronization, often by a tombstone containing the identifier and deletion version. If the client simply removes the row locally, a later pull may recreate it from the server. Tombstones can eventually be compacted when all relevant clients have advanced beyond the deletion, but premature removal risks resurrection.

StrategyStrengthRisk
Last-write-winsSimple automationSilent data loss and clock issues
Version rejectionPrevents overwritingRequires retry or resolution
Field mergePreserves independent editsCan violate domain rules
User resolutionBest for meaningful documentsHigh interaction cost
Operation logGood auditabilityMore complex replay and ordering

8. Security, Privacy, and Governance

Local storage expands the attack surface. A lost or compromised device may expose information even when the server is secure. Developers should apply data minimization: do not store information locally unless the application needs it.

Important practices include:

  • use secure credential storage for tokens and keys;
  • encrypt sensitive databases or files when the platform and threat model require it;
  • avoid placing personal data in logs, crash reports, or analytics;
  • protect backups and understand whether application data is included in them;
  • use least-privilege file and network permissions;
  • provide logout and account-removal behavior that addresses local copies;
  • define retention and deletion policies;
  • explain offline collection and synchronization in privacy notices.

Encryption at rest does not solve every problem. If the application can decrypt data while the device is unlocked, malware operating in the user's session may still access it. Key storage, device lock state, authentication, remote revocation, and server authorization remain relevant.

Offline authorization is difficult. A cached permission may become obsolete while the device is disconnected. Sensitive actions may need to be prohibited offline, limited by a short validity period, or recorded for later server authorization. The user experience should clearly distinguish “saved locally” from “accepted by the service.”

9. Testing and Operational Reliability

Offline-first systems require more than ordinary screen tests. Test at least:

  • first launch with an empty store;
  • application restart during a write;
  • no connectivity, intermittent connectivity, and captive portals;
  • duplicate responses and repeated requests;
  • server rejection and authentication expiry;
  • simultaneous edits on two devices;
  • migration from every supported schema version;
  • full storage, corrupt files, and insufficient permissions;
  • device clock changes and time-zone changes;
  • deletion and restoration of backups;
  • large datasets and slow queries.

Property-based and fault-injection testing are valuable. For example, a test can interrupt synchronization after every step and verify that restarting eventually produces a valid state. Observability should record operation identifiers, schema versions, synchronization duration, and failure categories without exposing private payloads.

Performance should be measured rather than guessed. Useful metrics include local read latency, transaction duration, database size, cache hit rate, outbox age, synchronization success rate, and the number of unresolved conflicts. A high cache hit rate is not beneficial if the cache returns dangerously stale data.

10. Illustrative Case: An Offline Field-Inspection Application

Background

Consider InspectPro, a fictional application used by building inspectors. Inspectors visit sites where cellular connectivity is unreliable. They record observations, attach photographs, and submit reports that may have legal and financial consequences.

Problem

An online-only design causes lost observations and prevents inspectors from seeing previously downloaded site information. A simple cache is inadequate because unsent observations must survive application restarts and must not be confused with disposable server results.

Analysis

The application distinguishes three authorities:

  • local drafts are authoritative for the inspector's current unsynchronized work;
  • the server is authoritative for submitted reports and access permissions;
  • cached reference data, such as inspection categories, is replaceable but must display its revision date.

The design uses a relational local database for reports, observations, and synchronization metadata. Photographs are files whose metadata is stored in the database. Preferences store display settings only.

Approach and solution

When an inspector adds an observation, a transaction writes the observation and an outbox operation. The photograph is first written to a temporary file, verified, and atomically moved to its permanent location; the database transaction then records its metadata. The interface reads from the local database and labels each report as Draft, Pending upload, Synchronized, or Conflict.

Each report carries a server revision. Upload requests include the report identifier, base revision, operation identifier, and changed fields. The server rejects an update based on an obsolete revision rather than silently overwriting another inspector's submission. A conflict screen shows the local and server versions, while immutable submitted reports require a new correction record rather than destructive editing.

A synchronization worker uploads small metadata operations and separately manages photograph transfer. If a photo upload fails, the report remains locally complete and the outbox records the pending attachment. Repeating the upload with the same operation identifier does not create duplicate attachments.

Outcome

Inspectors can work without connectivity, see their own changes immediately, and distinguish local completion from server acceptance. The design requires more states and testing than a simple online form, but it protects evidence and provides an audit trail.

Learning points

  1. Offline-first design begins with data authority and failure semantics.
  2. Files and database metadata should be coordinated carefully.
  3. Version checks are preferable to silent overwriting for consequential records.
  4. User-visible synchronization states reduce misunderstanding.
  5. Legal or safety-critical domains require retention, audit, and access controls beyond ordinary caching.

11. Contemporary Directions and Design Guidance

Modern mobile frameworks increasingly support reactive local databases, background task schedulers, encrypted stores, and server change feeds. These tools reduce implementation effort but do not decide business semantics. A framework may merge records technically while still producing an invalid invoice, duplicated booking, or unauthorized action.

Collaborative applications are exploring operational transformation and conflict-free replicated data types (CRDTs). Such approaches can provide mathematically structured convergence for selected data types, but they introduce metadata overhead and do not automatically solve authorization or domain constraints. They are most appropriate when the application can define valid commutative operations and tolerate their storage and conceptual complexity.

Artificial intelligence can assist with schema inspection, migration test generation, anomaly detection, and conflict explanations. It should not be allowed to invent silent data changes in sensitive records. Generated migrations and merge suggestions require deterministic tests, review, auditability, and a clear human override.

A sound implementation process is:

  1. Classify each data item by authority, sensitivity, lifetime, and size.
  2. Define user-visible behavior for offline, pending, rejected, and conflicting states.
  3. Choose the smallest storage mechanism that satisfies the requirements.
  4. Establish identifiers, versions, constraints, and transaction boundaries.
  5. Design migrations before releasing schema-dependent features.
  6. Implement idempotent synchronization with durable cursors and outbox records.
  7. Test crashes, retries, concurrency, storage failure, and privacy controls.
  8. Measure real behavior and revise policies based on evidence.

Chapter Summary

Mobile applications need several forms of local storage because preferences, files, structured records, credentials, and disposable remote results have different requirements. Preferences suit small settings; files suit binary content; relational databases suit related records and transactions; non-relational stores suit selected access patterns; and caches provide replaceable performance copies.

Reliable applications protect integrity through identifiers, validation, constraints, transactions, atomic file operations, and carefully tested migrations. A repository isolates application logic from storage and network mechanisms. In an offline-first workflow, local data is updated immediately and a durable outbox records work for later synchronization. Synchronization must handle retries, duplicate requests, remote changes, deletion tombstones, and explicit conflict policies.

Last-write-wins is simple but may lose data. Version rejection, field-level merging, operation logs, and user-assisted resolution are alternatives whose suitability depends on domain semantics. Security requires protected credentials, encryption where appropriate, data minimization, safe backups, privacy-aware logging, and explicit treatment of offline authorization. Finally, offline-first applications must be tested under crashes, migration, concurrency, unreliable networks, and storage failure—not only under ideal conditions.

Key Terms

Preferences: Small key-value settings used for configuration.

File storage: Persistent storage for documents and binary content.

Relational database: A structured store using tables, keys, relationships, and constraints.

Non-relational database: A database model such as document, key-value, graph, or wide-column storage.

Cache: A replaceable copy used to improve access performance.

Source of truth: The authoritative component when data copies disagree.

Serialization: Conversion of in-memory data into a storable representation.

Transaction: An atomic unit of database work.

Invariant: A condition that must remain valid after completed operations.

Repository: An abstraction exposing application data operations independently of storage details.

Offline-first: A design in which local data supports primary interaction without continuous connectivity.

Outbox: A durable queue of local operations awaiting synchronization.

Idempotency: Safety of repeating an operation without producing an additional effect.

Migration: A controlled change from one data schema to another.

Tombstone: A retained deletion marker used during synchronization.

Conflict: An incompatible result of concurrent changes.

Version token: A value used to detect whether data changed since it was read.

Data minimization: Storing and processing no more personal data than necessary.

Review Questions

Short Answer Questions

  1. Why is a cache different from durable user-generated data?
  2. Give two situations in which a relational database is preferable to preferences.
  3. What problem does an outbox solve in an offline-first application?
  4. Why should important file updates use temporary files and atomic replacement?
  5. What is a tombstone, and why is it needed for synchronized deletion?

Long Answer Questions

  1. Compare preferences, files, relational databases, non-relational databases, and caches. Include an appropriate use case and a major risk for each.
  2. Explain how repositories support separation of concerns and testability in a mobile application.
  3. Describe a complete bidirectional synchronization cycle, including retries, cursors, acknowledgements, and conflicts.
  4. Compare last-write-wins, version-based rejection, field-level merging, and user-assisted resolution.
  5. Design a migration strategy for an application that has changed its local schema over three released versions.

Analytical / Application Questions

  1. A shopping application allows users to edit a cart offline on two devices. Identify possible conflicts and propose a resolution policy that preserves inventory and pricing rules.
  2. Design the local data model and synchronization workflow for a mobile medical survey application. Address privacy, files, validation, authorization, and failure recovery.
  3. An application reports a high cache hit rate but users frequently see obsolete records. Analyze why the metric is insufficient and propose additional policies and measurements.

Multiple Choice Questions with Answers

Question 1

Which storage mechanism is most appropriate for a user-created photograph in a mobile application?

A. A preference key

B. A file, with metadata stored separately if needed

C. A Boolean configuration value

D. A synchronization cursor

Correct Answer: B. A file, with metadata stored separately if needed

Question 2

What is the principal purpose of an outbox in an offline-first application?

A. To store disposable thumbnails only

B. To replace database constraints

C. To retain local operations until they can be synchronized

D. To encrypt all application data automatically

Correct Answer: C. To retain local operations until they can be synchronized

Question 3

Why should a synchronization request include an operation identifier?

A. To choose the user interface theme

B. To support idempotent retries and prevent duplicate effects

C. To increase the size of downloaded images

D. To delete all older records

Correct Answer: B. To support idempotent retries and prevent duplicate effects

Question 4

Which statement best describes a cache?

A. It is always the authoritative copy of user data

B. It is a replaceable copy used to improve access

C. It must contain every application record permanently

D. It is a secure replacement for credential storage

Correct Answer: B. It is a replaceable copy used to improve access

Question 5

What is the main purpose of a database transaction when saving an edit and an outbox entry?

A. To ensure the related writes succeed or fail as one unit

B. To guarantee that the device has network connectivity

C. To remove the need for schema migration

D. To make all conflicts impossible

Correct Answer: A. To ensure the related writes succeed or fail as one unit

Question 6

Which conflict strategy explicitly prevents an update when the base version is obsolete?

A. Version-based rejection

B. Unbounded last-write-wins

C. Cache eviction

D. File compression

Correct Answer: A. Version-based rejection

Question 7

Why are deletion tombstones used in synchronization?

A. To make photographs smaller

B. To prevent a deleted record from being recreated by a later remote change

C. To store a user's password

D. To replace all primary keys

Correct Answer: B. To prevent a deleted record from being recreated by a later remote change

Question 8

Which practice is most appropriate for storing authentication tokens?

A. Plain text in a general preferences file

B. A platform-provided secure credential facility

C. A temporary image file

D. A cache with no access control

Correct Answer: B. A platform-provided secure credential facility

Question 9

What should an application generally do with a synchronization cursor?

A. Advance it before applying downloaded changes

B. Persist it only after the corresponding changes are applied successfully

C. Generate a new random value after every screen display

D. Store it only in volatile memory

Correct Answer: B. Persist it only after the corresponding changes are applied successfully

Question 10

Which testing scenario is especially important for offline-first systems?

A. Only testing with a fast and continuous network

B. Testing crashes and interruptions during synchronization

C. Testing only the color of buttons

D. Avoiding tests of old schema versions

Correct Answer: B. Testing crashes and interruptions during synchronization

Mobile Application Development
Chapter 6 of 15