GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/Advanced
Advanced/2026-05-24Advanced

SwiftData × Gemini API Offline Response Cache — Persisting and Reusing AI Responses on iOS

Design a SwiftData-backed cache layer for Gemini API responses so your iOS app keeps working in airplane mode and on flaky networks. Covers @Model schema, invalidation strategy, store-size discipline, and migration — all from production iOS experience.

Gemini API192SwiftDataiOS13OfflineArchitecture9

Premium Article

I have come to dislike apps that go silent the moment they lose signal. If a sentence the model produced a minute ago can reappear immediately, that is not "caching working" — it is "the user not feeling abandoned." On the subway or on a plane, the previous response simply renders again, quietly. The piece of engineering that delivers that experience is rarely glamorous: it is a small, carefully designed persistence layer.

When you ship indie iOS apps, you notice that wallpaper, calm, and manifestation apps open disproportionately often in places with poor connectivity — a subway platform, a plane, a parents' house up in the hills. Those are exactly the moments where an AI feature going silent feels cheap. After integrating Gemini API in earnest from 2025 onward, I found that "returning the previous response without calling the network" was directly tied to perceived production quality. This article walks through an architecture that uses SwiftData as the storage tier to persist and reuse Gemini API responses, covering both the implementation and the operational lessons.

Why app-side response caching, not just Gemini context caching

Gemini API offers context caching that is genuinely useful for reusing long system prompts and reference documents on the server side. But it cannot help when the device itself is offline. The pattern in this article — caching the response payload on the device — pays off in three concrete scenarios.

The user can re-open a paragraph the model just wrote, in airplane mode, as many times as they want. Cells re-rendered while the user scrolls (in a LazyVGrid or UICollectionView) do not need a fresh call; the previous response shows up instantly. For internal review tools that hit the same prompt repeatedly, token cost can drop by an order of magnitude.

You can implement the same idea with UserDefaults or a homemade JSON file, and that is fine up to a few hundred entries. Past a few thousand, query performance, schema evolution, and related-object management all collapse. In my wallpaper app, where description-generation entries reach the low thousands per day, moving to SwiftData cut the initial first-load time on cold start to under a third of what it used to be.

High-level architecture

There are three layers. First, the SwiftData @Model records — the storage tier. Second, ResponseCacheStore, which resolves prompts to keys to records — the repository tier. Third, GeminiResponder, which returns a cached hit or falls back to a live Gemini call — the use-case tier.

The SwiftUI view only knows about GeminiResponder. It does not know SwiftData exists, and it does not know the Gemini SDK exists. That separation matters later, when you want to swap storage to Realm or Core Data, or swap the model to on-device Gemma.

SwiftUI View
    │
    ▼
GeminiResponder (Use Case) ─── if hit ──→ Cached response
    │                                       ▲
    │ miss                                  │ save
    ▼                                       │
GeminiClient (Network) ─── response ───────┘
    │
    └─→ ResponseCacheStore (Repository)
            │
            ▼
        SwiftData @Model

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A @Model schema for Gemini responses, with prompt-hash keying for fast lookups
A three-axis invalidation policy combining TTL, model version, and explicit user refresh
Four hard-won lessons from running this pattern across a multi-million-download iOS portfolio
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Advanced2026-07-08
When Your Knowledge Base Shifts Mid-Run: Pinning File Search to an Execution Epoch for Consistent Agent Grounding
When a File Search store is updated while a Managed Agent is running, a single execution can mix old and new grounding. Borrowing MVCC ideas, pinning an execution epoch keeps one agent run's evidence consistent. Here is the design and implementation.
Advanced2026-05-31
The Day You Switch Gemini Embedding Models: Designing a Zero-Downtime Reindex
Upgrade your embedding model and every vector you ever stored becomes incompatible. Here is a dual-index design for re-embedding hundreds of thousands of vectors without downtime, complete with a resumable reindex job and a query-side abstraction layer.
Advanced2026-07-17
A Japanese query won't surface its English twin — when embeddings notice language before meaning
Embed a translation pair with gemini-embedding-2 and the two halves won't be nearest neighbours, because language itself inflates similarity. Here is how I measured cross-lingual recall using translation pairs as ground truth, and what happened when I subtracted the language centroid.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →