A privacy-first iOS GIF keyboard that reads from your iCloud Drive. Zero network access, zero tracking, zero data collection.
- 🔒 100% Private — No network code in the keyboard extension. Full access is required only to write GIFs to the system pasteboard, not for network access.
- 📁 iCloud Drive Based — Just drop GIFs into a folder, no server needed
- 🔍 Smart Search — Search by filename or macOS Finder tags
- ⚡ Fast & Lightweight — Thumbnails cached locally, ~30MB memory limit
- 🎨 Animation Preserved — GIFs paste correctly into iMessage, Threads, Twitter, etc.
- You create a
GifKeyboardfolder in iCloud Drive - You add GIF files to that folder (on Mac or iPhone)
- The companion app syncs GIFs to a local cache with thumbnails
- The keyboard extension reads from the cache (no iCloud access needed during typing)
- Tap a GIF to copy it to the pasteboard — it pastes as an animated GIF
- iOS 17.0 or later
- Xcode 16.0 or later
- iCloud Drive enabled
- Development team for code signing
-
Clone and open the project:
git clone https://github.com/Xatter/PrivateGifKeyboard.git cd PrivateGifKeyboard xcodegen generate open GifKeyboard.xcodeproj -
Set your development team:
- Select the project in Xcode
- Go to "Signing & Capabilities"
- Set your Team ID for both
GifKeyboardandGifKeyboardExtensiontargets
-
Build and deploy:
# Update DEVICE_UDID and TEAM_ID in deploy.sh first ./deploy.shOr build for simulator:
./build.sh
On Mac:
- Open Finder
- Go to iCloud Drive (in the sidebar)
- Create a folder named
GifKeyboard - Drop your GIF files into this folder
- (Optional) Tag your GIFs with Finder tags like "reaction", "funny", "work"
- Right-click a GIF → Tags → add tags
- Tags become searchable in the keyboard
On iPhone:
- Open the Files app
- Tap Browse → iCloud Drive
- Create a folder named
GifKeyboard(tap the ••• menu → New Folder) - Add GIFs by:
- Saving from Safari/Messages/etc. to Files → iCloud Drive/GifKeyboard
- Using the share sheet from Photos → Save to Files → GifKeyboard
- AirDrop from Mac → Save to iCloud Drive/GifKeyboard
- Open the GifKeyboard app on your iPhone
- Complete the setup walkthrough
- Tap Sync Now to import your GIFs
- Go to Settings → General → Keyboard → Keyboards → Add New Keyboard
- Select GifKeyboard
- (Optional) Tap Edit to reorder keyboards (put GifKeyboard near the top)
- Open any app (Messages, Twitter, Threads, etc.)
- Tap the 🌐 globe icon to switch to GifKeyboard
- Search for a GIF or scroll through the grid
- Tap a GIF to copy it
- Tap the 🌐 globe icon to switch back to your regular keyboard
- Paste (long-press text field → Paste)
GifKeyboard/
├── GifKeyboard/ # Companion app (SwiftUI)
│ ├── Views/ # SetupView, GifGridView
│ ├── ViewModels/ # AppViewModel
│ └── GifKeyboardApp.swift # Entry point + background refresh
├── GifKeyboardExtension/ # Keyboard extension (UIKit)
│ └── KeyboardViewController.swift
├── Shared/ # Code shared between app and extension
│ ├── Models/
│ │ └── GifEntry.swift # Data model
│ └── Services/
│ ├── GifSearchService.swift # Search filtering
│ ├── GifIndexStore.swift # JSON persistence
│ ├── GifPasteboardService.swift # Pasteboard copy
│ ├── SyncService.swift # Sync orchestration
│ ├── TagExtractor.swift # Finder tag extraction
│ └── ThumbnailGenerator.swift # JPEG thumbnail generation
├── GifKeyboardTests/ # Unit tests (28 tests, all passing)
└── docs/plans/ # Design and implementation docs
macOS Finder tags → iCloud Drive/GifKeyboard/*.gif
↓
(Companion App syncs)
↓
App Group Container (local cache)
├── gifs/ (full GIFs)
├── thumbnails/ (JPEG previews)
└── index.json (metadata + tags)
↓
(Keyboard Extension reads)
↓
Search & Display Grid
↓
Tap → Copy to Pasteboard
- No network access — Full access is requested only to write GIFs to
UIPasteboard.general. The keyboard extension contains no network code. - No keylogging — The keyboard never sees what you type in other apps
- No analytics — No telemetry, no crash reporting, no tracking
- No recents tracking — We don't log which GIFs you use
- Local-only — All data stays on your device and your iCloud
./build.shOr manually:
xcodebuild test \
-project GifKeyboard.xcodeproj \
-scheme GifKeyboard \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest'Test Coverage: 28 tests covering:
- JSON serialization (GifEntry model)
- Search filtering (filename + tag matching)
- Finder tag extraction (with color suffix stripping)
- Thumbnail generation (first frame, scaled JPEG)
- Pasteboard service (animation preservation, byte-identical round-trip)
- Index persistence (save/load, empty state handling)
- Sync service (add/remove/skip logic)
The companion app registers a BGAppRefreshTask that runs approximately every hour (when the device is idle). This keeps the keyboard's GIF index up to date without requiring you to manually open the app.
To test background refresh in the simulator:
# Schedule a background task immediately
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.gifkeyboard.app.refresh"]GIFs aren't showing up in the keyboard:
- Open the GifKeyboard app and tap "Sync Now"
- Check that the
GifKeyboardfolder exists in iCloud Drive - Make sure GIF files have the
.gifextension (case-insensitive)
Keyboard doesn't appear in Settings:
- Rebuild and reinstall the app
- Make sure you selected a development team in Xcode signing settings
GIFs paste as static images:
- This shouldn't happen — our tests verify animation preservation
- If it does, please file an issue with the app you're pasting into
Search isn't finding my GIFs:
- Search matches filename (including extension) and Finder tags
- Try typing part of the filename without the extension
- Check that tags are set correctly in Finder (right-click → Tags)
MIT License — see LICENSE file for details.
Built with:
- Swift + SwiftUI (companion app)
- UIKit (keyboard extension)
- ImageIO framework (GIF handling)
- BackgroundTasks framework (automatic sync)
- XcodeGen (project generation)
Design philosophy: Privacy-first, local-first, no servers, no tracking.