SQLCipher not working on iOS release builds

Hi we have an app that uses SQLCipher it seems to work without any issue when building a DEBUG configuration (Also through TestFlight) however if we build a RELEASE configuration the following query returns an empty array:

pragma cipher_version

Just a little bit about our app. We have both a iOS (NOT working) and Android app that have shared code through flutter and both sides have still native code that is in the process of being flutterized. On the iOS side we have a mix between Objective-C and Swift. Our Podfile looks as follows

  pod 'Google-Mobile-Ads-SDK'
  ...
  
  pod 'GoogleMaps'
  pod 'Google-Maps-iOS-Utils/Clustering'
  pod 'GooglePlaces'

  pod 'FirebaseCore', :modular_headers => true
  pod 'Firebase/Crashlytics', :modular_headers => true
  pod 'Firebase/Analytics', :modular_headers => true
  pod 'Firebase/Messaging', :modular_headers => true
  pod 'Firebase/RemoteConfig', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true
  pod 'Realm', '10.5.1'
  pod 'SQLCipher', '~> 4.5.4', :modular_headers => true
  pod 'GRDB.swift/SQLCipher'
  pod 'GRDB.swift'

On the flutter side we use

sqlcipher_flutter_libs: 0.5.7

XCODE: 16.1
Flutter: 3.16.9 Dart 3.2.6

currently we are pinned to these versions due to breaking changes needed on our end. We already tried to remove all references/links to sqlite3 from other pod libraries. Furthermore we also tried to move the linker flag for SQLCipher to the top for both the project and the pods project xconfig file. However this seems not to help, I came to the conclusion that it must be something in the archiving process that breaks the thing, otherwise it wouldn’t be broken in the DEBUG configuration. E.g. Android uses ProGuard and as far as I understood there are some special rules for the SQLCipher part.

Please help if anybody has some clues for us to get this thing working would be just great…thanks in advance.

UPDATE:

I updated the Podfile and the version SQLCipher to 4.5.7 to see if that helps however still the same issue. Interestingly on SQLCipher 4.5.4 in DEBUG I saw that the pragma cipher_version returned 4.5.7 which is strange.

Updated Podfile:

 #removed GRDB.swift
 pod 'SQLCipher', '~> 4.5.7', :modular_headers => true
 pod 'GRDB.swift/SQLCipher'

also the flutter lib was pushed to: 0.6.2 to support 4.5.7

Pragma in RELEASE:

@Peter_Plant

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

Your Podfile contains both GRDB.swift/SQLCipher subspec AND GRDB.swift standard.

You’ll want to remove the GRDB.swift standard pod as mentioned in the GRDB.swift encryption documentation here: GitHub - groue/GRDB.swift: A toolkit for SQLite databases, with a focus on application development

Make sure you remove any existing pod 'GRDB.swift' from your Podfile. GRDB.swift/SQLCipher must be the only active GRDB pod in your whole project, or you will face linker or runtime errors, due to the conflicts between SQLCipher and the system SQLite.

Unfortunately this didn’t work. Release builds are still failing if distributed through Testflight but as always work for local ones

@Peter_Plant

If PRAGMA cipher_version isn’t returning any results at runtime then that means that SQLCipher isn’t being properly linked within your application. This typically occurs because of mis-configuration or conflicting linking of system/other sqlite3.

You mentioned removing all references/links to sqlite3 from other pod libraries, that is typically one of the causes.

For example, in the portion of the Podspec you shared, these pods all have transitive dependencies on standard sqlite3:

Google-Mobile-Ads-SDK: Specs/Specs/5/9/a/Google-Mobile-Ads-SDK/11.13.0/Google-Mobile-Ads-SDK.podspec.json at master · CocoaPods/Specs · GitHub

Firebase/Analytics: firebase-ios-sdk/FirebaseAnalytics.podspec at main · firebase/firebase-ios-sdk · GitHub

Firebase/Messaging: firebase-ios-sdk/FirebaseMessaging.podspec at main · firebase/firebase-ios-sdk · GitHub

I’d recommend some further troubleshooting with removing some of these pods/functionality to see if you can identify what’s causing the issue.

But why does it properly work with the DEBUG configuration, also if the build is uploaded to Testflight and distributed it works and cipher_version returns the currently active sql_cipher.

If one of the above mentioned pods would create some sort of conflict would this not impact also the DEBUG configuration?

@Peter_Plant

Hard to say what’s causing the issue for you without seeing your entire project, configuration, and workflow for how you are generating the builds/archiving/releasing.

It’s possible that one of the other pods which has a transitive dependency on sqlite3 is doing something to cause it.

It’s possible that some of your flags are different for debug vs release builds, but I suspect that the TestFlight build would fail as well then. From your response before the last you mentioned the TestFlight build isn’t returning any result of the cipher_version:

Release builds are still failing if distributed through Testflight but as always work for local ones

But then you mentioned in your most recent response that it’s working:

if the build is uploaded to Testflight and distributed it works and cipher_version returns the currently active sql_cipher.

In the SQLCipher iOS integration instructions, there is an example of a post-install hook you can add which removes linking standard sqlite3 in Other Linker Flags of the aggregate target: SQLCipher Community Edition - Adding Full Database Encryption for SQLite to iOS and macOS | Zetetic

You mentioned using Flutter, there’s a link in the sqlcipher_flutter_lib documentation: sqlcipher_flutter_libs | Flutter package with a similar post install hook: Force quiting our app throws `file is not a database` error at startup of the app · Issue #1810 · simolus3/drift · GitHub

If the post-install hook doesn’t work my recommendation for troubleshooting further is:

  1. Remove all dependencies which you think may be conflicting.
  2. Build your app with just GRDB.swift/SQLCipher subspec and confirm that you’re able to get the PRAGMA cipher_version from that.
  3. Re-add dependencies one by one and rebuild each time to isolate which dependency could be causing the issue and investigate that further

If you’re unable to get the cipher_version in step 2, then that most likely means that you have something mis-configured within your project.

If none of this works, you might want to consider raising an issue in the sqlcipher flutter libs project and creating a simple example application which reproduces the issue, upload it to GitHub with instructions for how to build it and link it over in this post/the sqlcipher flutter libs project issue.