Apple has recently released Xcode 9, along with new SDKs (e.g. iOS 11, watchOS 4, etc), with new features and enhancements. Most projects that include recent versions of SQLCipher shouldn’t have any problems upgrading. However, there are some changes in the SDKs, so we have prepared important recommendations for SQLCipher developers that run into errors after upgrading.
Note: Before proceeding, be sure that all projects implement the separately documented recommended changes related to SQLCipher link ordering, run-time checks, and testing / validation.
Changes in Xcode 9
Apple has always included a header file, sqlite3.h
, in past releases of their SDKs. This header file defines the standard API interface for SQLite. Because the same interface is used with SQLCipher, it was formerly possible to use the SDK header file in place of SQLCipher’s packaged sqlite3.h
. However, with the new release of Xcode 9 and the latest SDKs, the defintitions of sqlite3_key
and sqlite3_rekey
are missing from the Xcode 9 SDK sqlite3.h
file.
This change means that if a project is not setup correctly it will be unable to locate SQLCipher’s sqlite3.h
, resulting in compile time errors like these:
Implicit declaration of function ‘sqlite3_key’ is invalid in C99
Implicit declaration of function ‘sqlite3_rekey’ is invalid in C99
Note that these errors indicate a problem with the project setup, not an issue with SQLCipher itself. In other words, under earlier versions of Xcode it was possible to have an improperly configured project that would still compile anyway. Now, under Xcode 9, it is mandatory that SQLCipher’s sqlite3.h
be used by the compiler via the Header Search Path
in project or target Build Settings.
Recommended Resolutions
The appropriate resolution depends on how you are including SQLCipher in your Xcode project.
All Integration Methods
Before making any other changes, first, ensure that -DSQLITE_HAS_CODEC
is present in the the Other C Flags
property of the top level project or target Build Settings.
SQLCipher Commercial Edition / Enterprise
When using offical Zetetic package distributions, locate the Header Search Paths
property in the top level project Build Settings and ensure that $(PROJECT_DIR)/sqlcipher-static-ios/include
is present. If necessary, adjust according to the the path to the sqlite3.h you received as part of the package.
sqlcipher.xcodeproj
When using the sqlcipher.xcodeproj included in the SQLCipher git repository, locate the Header Search Paths
property in the top level project Build Settings and ensure that $(PROJECT_DIR)/sqlcipher
is present. If you have located the sqlcipher submodule elsewhere in your project structure then adjust the path as appropriate.
SQLCipher CocoaPod with use_frameworks!
When using the SQLCipher CocoaPod (or any other Pod that depends on SQLCipher, e.g. FMDB), it is necessary to make a special adjustment if the project Podfile
contains the use_frameworks!
directive. This appears to be the result of a CocoaPods issue that disables the creation of header links under Pods/Headers when use_framworks!
is enabled. This makes it impossible for Xcode 9 to resolve the proper sqlite3.h
file included with the SQLCipher Pod.
The simplest work around is to add a post_install
hook in the project Podfile tha creates a link in Pods/Headers/Private
. That folder is is automatically included in the Header Search Paths
by CocoaPods.
post_install do | installer |
print "SQLCipher: link Pods/Headers/sqlite3.h"
system "mkdir -p Pods/Headers/Private && ln -s ../../SQLCipher/sqlite3.h Pods/Headers/Private"
end
SQLCipher CocoaPod without use_frameworks!
If implicit declaration warnings are present using the SQLCipher CocoaPod, but without the use_frameworks!
directive, then it is possible the project Build Settings are overriding the default CocoaPod settings. In this case, inspect the project settings and each target to remove any manual Header Search Paths
setting, or add $(inherited)
to the setting if manual overrides are necessary. If the project is setup incorrectly running pod install
will report warnings about the project HEADER_SEARCH_PATH
overriding Pod settings. Change the project configuration to eliminate those warnings.