FMDB: the Objective-C SQLite wrapper that still ships
A Cocoa / Objective-C wrapper around SQLite
At a glance
- What is it?
- FMDB wraps SQLite for Cocoa apps and installs through CocoaPods, Carthage or Swift Package Manager. It is a thin, stable layer, and the repository's last push was on 2026-03-15.
- Who is it for?
- FMDB suits teams maintaining Objective-C or mixed Cocoa codebases that already depend on SQLite and want an FMDatabase object rather than raw C calls. It is the wrong choice for a new Swift-only app that wants typed queries, since GRDB and SwiftData sit closer to that style.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Objective-C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What FMDB covers that raw SQLite does not
SQLite's C API is a small set of functions around sqlite3_open, prepared statements and result stepping. FMDB puts Objective-C objects on top of that: FMDatabase for a connection, FMResultSet for iterating rows, and string-based methods for executing statements. The README frames the project simply as "an Objective-C wrapper around SQLite", and it points readers at the SQLite FAQ and documentation before anything else, which tells you where the project expects the real learning to happen. The audience is Cocoa developers, mostly on iOS and macOS, who want SQLite without writing C. It is not a database engine, not an ORM, and not a query builder. If you want typed models and change observation, FMDB is the wrong layer.
How the wrapper is structured
The repository splits into src/ for the library and Tests/ for the test target, with an Xcode project alongside a Package.swift manifest. That layout matters: FMDB ships as both a classic Xcode framework and a Swift Package, and the two paths are not identical. The podspec exposes subspecs, so the same source can be built plain, with FTS, with the bundled SQLite amalgamation, or with SQLCipher. Memory management is handled at compile time. The README states that FMDB "will figure out which you are using at compile time and do the right thing" for ARC or manual retain and release, so the same source compiles into both kinds of project. Version 2.7 was audited for nullability and moved external interfaces toward properties, which the README describes as a fairly significant change for Swift developers and a fairly seamless one for Objective-C developers, with the caveat that previously exposed ivars are gone.
Installing FMDB with CocoaPods, Carthage or Swift Package Manager
CocoaPods is the path the README documents first. Run pod init in your project directory to generate a Podfile, then add the pod line and install. The subspecs are commented out in the template, so uncomment only the variant you need.
target 'MyApp' do
use_frameworks!
pod 'FMDB'
# pod 'FMDB/FTS' # FMDB with FTS
# pod 'FMDB/standalone' # FMDB with latest SQLite amalgamation source
# pod 'FMDB/SQLCipher' # FMDB with SQLCipher
endAfter editing the Podfile, run pod install. The README is explicit that you then open the .xcworkspace rather than the .xcodeproj. If you need encryption, the README states you must use the FMDB/SQLCipher subspec, because that subspec declares SQLCipher as a dependency and lets FMDB compile with the -DSQLITE_HAS_CODEC flag.
Carthage takes two commands from your project's main directory:
echo ' github "ccgus/fmdb" ' > ./Cartfile
carthage updateFor Swift Package Manager, declare the dependency and the product. The README's example pins with upToNextMinor from 2.7.12.
.package(
name: "FMDB",
url: "https://github.com/ccgus/fmdb",
.upToNextMinor(from: "2.7.12")),A first real use is opening a database and setting a key when you built with SQLCipher. The README gives this shape, where db.setKey is available through the FMDatabase+SQLCipher methods that the SQLCipher trait enables:
import FMDB
let db = FMDatabase(path: NSTemporaryDirectory().appending("tmp.db"))
guard db.open() else {
print("Unable to open datbase")
return
}
db.setKey("sup3rs3cr3t")
// perform database operations to read from/write to the encrypted database
db.close()If db.open() returns false, the guard branch prints and returns; that is the failure signal, not an exception.
Encrypting an existing database and the Xcode trait gap
SQLCipher support through Swift Package Manager is newer and rougher than the CocoaPods route. You enable it with the SQLCipher trait on the package dependency, and the README notes that as of Xcode 16.4 (16F6) there is no direct way in the Xcode UI to select trait variations. The documented workaround is a local wrapper package that pulls in FMDB with the trait enabled, which you then add as a dependency inside Xcode. That is extra project structure for something the podspec expresses as one subspec line. Converting a plaintext database is done in SQL rather than through a dedicated API: attach an encrypted database with a key, run sqlcipher_export against the attached alias, then detach. The README's example uses ATTACH DATABASE ? AS encrypted KEY ? with the export path and passphrase as bound values, then SELECT sqlcipher_export('encrypted') and DETACH DATABASE encrypted. Note the export target must not exist beforehand.
Where FMDB is the wrong tool
FMDB gives you strings, not types. Statements are passed as text and values as arrays, so a mistyped column name surfaces at runtime when the statement fails, not at compile time. There is no migration system, no schema versioning and no rollback story in the README; the README does not document rollback at all. Concurrency is on you: FMDatabase is a connection, and the README's own opening advice is to read the SQLite documentation top to bottom, which is where questions about threading and locking actually get answered. If your app is Swift-only and you want value observation, typed records or query interfaces checked by the compiler, FMDB asks you to build all of that yourself. And if you are not on Apple platforms, FMDB's Objective-C and Cocoa framing is dead weight.
FMDB compared with GRDB and SwiftData
GRDB is the alternative that comes up most in the related searches around this project, and the difference is architectural rather than cosmetic. GRDB is a Swift library that models rows as Codable records, offers query interfaces built in Swift, and includes observation of database changes; FMDB stays at the level of executing SQL strings and stepping a result set. That means GRDB can catch some mistakes at compile time that FMDB only reports when a statement runs. The trade is control and age: FMDB's API is close to SQLite itself, which makes it predictable for developers who already know SQL and want the underlying statements visible. Realm appears in the same searches, but it is a different engine with its own storage format, so it is not a drop-in comparison; moving to it means moving data, not just changing a wrapper.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-03-15, so work has happened within the last six months. Releases are infrequent and small: 2.7.12 is described as "The one with CocoaPods + SPM + SQLCipher fixes", and 2.7.11 and 2.7.9 are both described as CocoaPods-related. That pattern suggests maintenance aimed at keeping the packaging working rather than adding features. The upgrade cost is concentrated in packaging and in the 2.7 interface change, where nullability auditing and the shift from methods to properties affect Swift callers most; the README warns that ivars previously exposed in the public interface are no longer available. The licence file is LICENSE.txt, and the repository metadata reports the licence as NOASSERTION, meaning GitHub could not match it to a known licence identifier. Read LICENSE.txt yourself before shipping, and note that the SQLCipher subspec pulls in a separate dependency with its own terms. Nothing here is legal advice.
Editorial conclusion
FMDB suits teams maintaining Objective-C or mixed Cocoa codebases that already depend on SQLite and want an FMDatabase object rather than raw C calls. It is the wrong choice for a new Swift-only app that wants typed queries, since GRDB and SwiftData sit closer to that style. Before adopting, confirm the SQLCipher path you need (the FMDB/SQLCipher subspec or the SQLCipher trait in Swift Package Manager), and check whether your Xcode version exposes trait selection in the UI, because the README states that as of Xcode 16.4 (16F6) there is no direct way to pick trait variations there.
Frequently asked questions
How do I install FMDB in an iOS project?
Add the pod 'FMDB' line to your Podfile after running pod init, then run pod install and open the .xcworkspace instead of the .xcodeproj. Carthage and Swift Package Manager are also documented, with the package pinned from 2.7.12 in the README example.
How do I use FMDB with SQLCipher encryption?
With CocoaPods you must use the FMDB/SQLCipher subspec, which declares SQLCipher as a dependency and compiles FMDB with the -DSQLITE_HAS_CODEC flag. With Swift Package Manager you enable the SQLCipher trait, which adds a dependency on SQLCipher.swift and enables the FMDatabase+SQLCipher methods such as setKey.
Does FMDB work with ARC and manual memory management?
Yes. The README states that FMDB will figure out which style you are using at compile time and do the right thing, so the same source can be used in either kind of Cocoa project.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ccgus-fmdb)