# Integrating SQLCipher into a Core Data project, but not encrypting Core Data store

**URL:** https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740
**Category:** SQLCipher
**Created:** [January 27, 2023, 10:40am UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740 "2023-01-27T10:40:50Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![BrendanD](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/brendand/32/87_2.png) [@BrendanD](https://discuss.zetetic.net/u/BrendanD)
#### Post date: [January 27, 2023, 10:40am UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740/1 "2023-01-27T10:40:50Z")

</div>

My app is now using Core Data (SQLite store) AND a separate SQLite database. My Core Data part is where my static schema is stored and the SQLite store is where my dynamic schema is stored. Tables in the database and columns in the tables can be added and deleted. That’s the dynamic part. I’m doing it this way for flexibility and performance reasons. So everything has been working great up until the next thing I need to do. Encryption.

I want to encrypt the SQLite database using SQLCipher. I’m using cocoapods to integrate SQLCipher with the following parameters in my Podfile:

```auto
target 'TFCoreMac' do
        platform :osx, '12.0'
        pod 'FMDB'
        pod 'FMDB/SQLCipher'
end

post_install do |installer_representation|
  installer_representation.pods_project.targets.each do |target|
    if target.name == 'TFCoreMac'
      target.build_configurations.each do |config|
        config.build_settings['OTHER_CFLAGS'] ||= ['$(inherited)']
        config.build_settings['OTHER_CFLAGS'] << '-DSQLITE_HAS_CODEC -DSQLITE_POWERSAFE_OVERWRITE=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_THREADSAFE=2 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS4_UNICODE61'
      end
    end
  end
end

```

The problem I’m having is the version of SQLite that my app seems to be using is the built-in system SQLite version that Core Data is using, which does not support encryption.

Is there a way to allow Core Data to do its own thing with SQLite while other parts of my app use the SQCipher version of SQLite? Or can I get Core Data to use the same SQLite build that SQLCipher is using?

Some ideas of what I can try would be very helpful and appreciated. Thanks.

---

<div class="post-metadata">

### Author: ![mmoore](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mmoore/32/858_2.png) [@mmoore](https://discuss.zetetic.net/u/mmoore)
#### Post date: [January 27, 2023, 3:17pm UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740/2 "2023-01-27T15:17:48Z")

</div>

Hi @BrendanD

Thank you for your interest in SQLCipher and for posting to the discussion forum.

One thing I noticed is that you’re using both the standard FMDB pod and the FMDB/SQLCipher pod, you should only need to use the FMDB/SQLCipher pod (which includes all the standard FMDB stuff + SQLCipher).

> Is there a way to allow Core Data to do its own thing with SQLite while other parts of my app use the SQCipher version of SQLite? Or can I get Core Data to use the same SQLite build that SQLCipher is using?

We _ **DO NOT SUPPORT** _ using SQLCipher with a project that includes a separate sqlite3 dependency, including via CocoaPods. That sort of configuration carries multiple inherent risks, including undefined behavior, deadlocks, loss of data, loss of encryption functionality, etc.

That being said, you may want to review this document: [Important Advisory: SQLCipher with Xcode 8 and new SDKs](https://discuss.zetetic.net/t/important-advisory-sqlcipher-with-xcode-8-and-new-sdks/1688) – specifically the section under Project Setup and Linking which has instructions to ensure SQLCipher is linked into your Application first.

---

<div class="post-metadata">

### Author: ![BrendanD](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/brendand/32/87_2.png) [@BrendanD](https://discuss.zetetic.net/u/BrendanD)
#### Post date: [January 27, 2023, 9:11pm UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740/3 "2023-01-27T21:11:27Z")

</div>

Hi @mmoore

Thanks for the help! That was the key! Adding the `-framework SQLCipher` entry to the `Other Linker Flags` setting at the project level.

Also thanks for the warning about using SQLite with another dependency. I’ll have to keep an eye on that. I know some people are using SQLCipher with Core Data in the Encrypted Core Data project. But that project hasn’t been updated in many years and I’m reluctant to rely on something old like that. That’s why I’m leaving my Core Data store unencrypted and SQLCipher will be used just to encrypt records data in a separate SQLite database file.

There is a minor version number difference between the Apple supplied SQLite (on Ventura). Ventura has 3.39.5 and SQLCipher has 3.39.4. Hopefully that’s just a minor difference and nothing consequential.

---

<div class="post-metadata">

### Author: ![BrendanD](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/brendand/32/87_2.png) [@BrendanD](https://discuss.zetetic.net/u/BrendanD)
#### Post date: [January 27, 2023, 9:45pm UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740/4 "2023-01-27T21:45:54Z")

</div>

Actually it turns out just having that extra `FMDB` pod in my `Podfile` is what caused the built-in SQLite version to be used. The `Other Linker Flags` option didn’t make a difference as I took it out to test and with just having `FMDB/SQLCipher` in my `Podfile` allowed the SQLCipher version 3.39.4 to be loaded instead of the built-in 3.39.5.

But your warning does have me worried a bit. There are quite a few differences in the way the built-in SQLite is compiled vs. the SQLCipher cocoa pods version.

Apple’s SQLite 3.39.5 version:  
ATOMIC\_INTRINSICS=1  
BUG\_COMPATIBLE\_20160819  
CCCRYPT256  
COMPILER=clang-14.0.0  
DEFAULT\_AUTOVACUUM  
DEFAULT\_CACHE\_SIZE=2000  
DEFAULT\_CKPTFULLFSYNC  
DEFAULT\_FILE\_FORMAT=4  
DEFAULT\_JOURNAL\_SIZE\_LIMIT=32768  
DEFAULT\_LOOKASIDE=1200,102  
DEFAULT\_MEMSTATUS=0  
DEFAULT\_MMAP\_SIZE=0  
DEFAULT\_PAGE\_SIZE=4096  
DEFAULT\_PCACHE\_INITSZ=20  
DEFAULT\_RECURSIVE\_TRIGGERS  
DEFAULT\_SECTOR\_SIZE=4096  
DEFAULT\_SYNCHRONOUS=2  
DEFAULT\_WAL\_AUTOCHECKPOINT=1000  
DEFAULT\_WAL\_SYNCHRONOUS=1  
DEFAULT\_WORKER\_THREADS=0  
ENABLE\_API\_ARMOR  
ENABLE\_BYTECODE\_VTAB  
ENABLE\_COLUMN\_METADATA  
ENABLE\_DBSTAT\_VTAB  
ENABLE\_FTS3  
ENABLE\_FTS3\_PARENTHESIS  
ENABLE\_FTS3\_TOKENIZER  
ENABLE\_FTS4  
ENABLE\_FTS5  
ENABLE\_LOCKING\_STYLE=1  
ENABLE\_NORMALIZE  
ENABLE\_PREUPDATE\_HOOK  
ENABLE\_RTREE  
ENABLE\_SESSION  
ENABLE\_SNAPSHOT  
ENABLE\_SQLLOG  
ENABLE\_STMT\_SCANSTATUS  
ENABLE\_UNKNOWN\_SQL\_FUNCTION  
ENABLE\_UPDATE\_DELETE\_LIMIT  
HAS\_CODEC\_RESTRICTED  
HAVE\_ISNAN  
MALLOC\_SOFT\_LIMIT=1024  
MAX\_ATTACHED=10  
MAX\_COLUMN=2000  
MAX\_COMPOUND\_SELECT=500  
MAX\_DEFAULT\_PAGE\_SIZE=8192  
MAX\_EXPR\_DEPTH=1000  
MAX\_FUNCTION\_ARG=127  
MAX\_LENGTH=2147483645  
MAX\_LIKE\_PATTERN\_LENGTH=50000  
MAX\_MMAP\_SIZE=1073741824  
MAX\_PAGE\_COUNT=1073741823  
MAX\_PAGE\_SIZE=65536  
MAX\_SQL\_LENGTH=1000000000  
MAX\_TRIGGER\_DEPTH=1000  
MAX\_VARIABLE\_NUMBER=500000  
MAX\_VDBE\_OP=250000000  
MAX\_WORKER\_THREADS=8  
MUTEX\_UNFAIR  
OMIT\_AUTORESET  
OMIT\_LOAD\_EXTENSION  
STMTJRNL\_SPILL=131072  
SYSTEM\_MALLOC  
TEMP\_STORE=1  
THREADSAFE=2  
USE\_URI

SQLCipher’s 3.39.4 version:

ATOMIC\_INTRINSICS=1  
COMPILER=clang-14.0.0  
DEFAULT\_AUTOVACUUM  
DEFAULT\_CACHE\_SIZE=-2000  
DEFAULT\_FILE\_FORMAT=4  
DEFAULT\_JOURNAL\_SIZE\_LIMIT=-1  
DEFAULT\_MMAP\_SIZE=0  
DEFAULT\_PAGE\_SIZE=4096  
DEFAULT\_PCACHE\_INITSZ=20  
DEFAULT\_RECURSIVE\_TRIGGER  
DEFAULT\_SECTOR\_SIZE=4096  
DEFAULT\_SYNCHRONOUS=2  
DEFAULT\_WAL\_AUTOCHECKPOINT=1000  
DEFAULT\_WAL\_SYNCHRONOUS=2  
DEFAULT\_WORKER\_THREADS=0  
ENABLE\_COLUMN\_METADATA  
ENABLE\_FTS3  
ENABLE\_FTS3\_PARENTHESIS  
ENABLE\_FTS4  
ENABLE\_FTS5  
ENABLE\_LOAD\_EXTENSION  
ENABLE\_MEMORY\_MANAGEMENT  
ENABLE\_RTREE  
ENABLE\_STAT4  
ENABLE\_UNLOCK\_NOTIFY  
HAS\_CODEC  
MALLOC\_SOFT\_LIMIT=1024  
MAX\_ATTACHED=10  
MAX\_COLUMN=2000  
MAX\_COMPOUND\_SELECT=500  
MAX\_DEFAULT\_PAGE\_SIZE=8192  
MAX\_EXPR\_DEPTH=1000  
MAX\_FUNCTION\_ARG=127  
MAX\_LENGTH=1000000000  
MAX\_LIKE\_PATTERN\_LENGTH=50000  
MAX\_MMAP\_SIZE=0x7fff0000  
MAX\_PAGE\_COUNT=1073741823  
MAX\_PAGE\_SIZE=65536  
MAX\_SQL\_LENGTH=1000000000  
MAX\_TRIGGER\_DEPTH=1000  
MAX\_VARIABLE\_NUMBER=99999  
MAX\_VDBE\_OP=250000000  
MAX\_WORKER\_THREADS=8  
MUTEX\_PTHREADS  
SOUNDEX  
SYSTEM\_MALLOC  
TEMP\_STORE=2  
THREADSAFE=1

I don’t know why THREADSAFE=1. I explicitly set it to 2 in my Podfile.

Do you see any of these differences to be troublesome?

---

<div class="post-metadata">

### Author: ![mmoore](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mmoore/32/858_2.png) [@mmoore](https://discuss.zetetic.net/u/mmoore)
#### Post date: [January 27, 2023, 10:59pm UTC](https://discuss.zetetic.net/t/integrating-sqlcipher-into-a-core-data-project-but-not-encrypting-core-data-store/5740/5 "2023-01-27T22:59:24Z")

</div>

@BrendanD

> [@BrendanD](#):
>
> Actually it turns out just having that extra `FMDB` pod in my `Podfile` is what caused the built-in SQLite version to be used. The `Other Linker Flags` option didn’t make a difference as I took it out to test and with just having `FMDB/SQLCipher` in my `Podfile` allowed the SQLCipher version 3.39.4 to be loaded instead of the built-in 3.39.5.

What was occurring since you were including both (FMDB + FMDB/SQLCipher pods) is that `-l"sqlite3"` was being automatically put in your Other Linker flags by the FMDB pod and `-framework SQLCipher` was after it (from the `FMDB/SQLCipher` pod) so standard sqlite was being linked first into your Application. After removing the standard FMDB, SQLCipher is now properly being linked first.

The C Flags used for the SQLCipher Pod are in the Podspec here: [https://github.com/sqlcipher/sqlcipher/blob/master/SQLCipher.podspec.json](https://github.com/sqlcipher/sqlcipher/blob/master/SQLCipher.podspec.json)

We don’t develop or maintain FMDB, but I believe there are a few more added in their Podspec as well.
