Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    SOLVED Qt 5.1 ios How to Bundle and use SQLite database in application

    Mobile and Embedded
    9
    28
    19489
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      Tsweti last edited by

      I want to store data in SQLite database and I want to write the database file to ios device.
      For Android creating the file in
      @
      QStandardPaths::writableLocation( QStandardPaths::HomeLocation )
      @

      is a working solution but for ios I cannot create the file there. The returned path for the ios device is: "/private/var/mobile/Applications/XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" .

      How can I get a path that i can write to?

      1 Reply Last reply Reply Quote 0
      • C
        CuteiOS last edited by

        This functionality is not available in Qt5.1. In any case, the folder you would be looking for is the "Documents" folder, and not the "Home" location. As the "Documents" folder is not part of the application bundle, you will need to do some startup code in your app which checks for the database and copies it to or creates it in the "Documents" folder if it's not already there. To find the path for the documents folder, you'll need to use the following code:

        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]);

        To convert the NSString to a QString, you'll need something like:

        static inline QString qt_mac_NSStringToQString(const NSString *nsstr)
        {
        CFStringRef str = reinterpret_cast<const CFStringRef>(nsstr);
        if (!str) return QString();

        CFIndex length = CFStringGetLength(str);
        if (length == 0) return QString();
        
        QString string(length, Qt::Uninitialized);
        CFStringGetCharacters(str, CFRangeMake(0, length), reinterpret_cast<UniChar *>(const_cast<QChar *>(string.unicode())));
        
        return string;
        

        }

        1 Reply Last reply Reply Quote 0
        • T
          Tsweti last edited by

          Do you know if the functionality will be included in Qt 5.2 ?

          1 Reply Last reply Reply Quote 0
          • J
            jraichouni last edited by

            Hi!

            I am using Qt 5.2.0.

            Is it possible to use QtSql with SQLITE on iOS?

            I tried it and my app runs great on the desktop. But it seems, as if the deployment to iOS Simulator does not deploy any sqldriver does it?

            Should it work by copying the sqldrivers folder from
            /Users/jamil/Qt5.2.0_ios/5.2.0/ios/plugins to the .app directory being installed on the device/ simulator and adding
            @app.addLibraryPath(app.applicationDirPath() + "/sqldrivers");@

            Cheers
            jraichouni

            1 Reply Last reply Reply Quote 0
            • SGaist
              SGaist Lifetime Qt Champion last edited by

              Hi,

              Yes it is, but Qt for iOS is a static build so you need to tell Qt to use the static plugin

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply Reply Quote 0
              • J
                jraichouni last edited by

                Ah, great!

                But how can I do that?

                Currently my .pro file contains

                QT += sql

                The class calling
                @
                QSqlDatabase::addDatabase("QSQLITE");
                @

                contains @#include <QtSql>@

                How do I tell Qt to use the static sqldriver?
                And where should what be deployed to?

                Cheers
                jraichouni

                1 Reply Last reply Reply Quote 0
                • SGaist
                  SGaist Lifetime Qt Champion last edited by

                  "Here":http://qt-project.org/doc/qt-5.0/qtcore/qtplugin.html#Q_IMPORT_PLUGIN

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply Reply Quote 0
                  • J
                    jraichouni last edited by

                    Hi, thanks for that, but it's what
                    I've tried without success.
                    Xcode did not compile that.
                    I am going to prepare a small but
                    complete example project to list it here
                    tomorrow.

                    Cheers
                    jraichouni

                    1 Reply Last reply Reply Quote 0
                    • J
                      jraichouni last edited by

                      Here is an example:
                      @

                      sqlite_on_ios.pro

                      TEMPLATE = app
                      QT += qml quick
                      QTPLUGIN += qsqlite
                      QMAKE_INFO_PLIST += Info.plist
                      SOURCES += main.cpp
                      RESOURCES += main.qrc
                      cache()
                      @
                      @
                      <!-- main.qrc -->
                      <RCC><qresource prefix="/"> <file>main.qml</file> </qresource></RCC>
                      @
                      @
                      // main.qml
                      import QtQuick 2.0
                      Rectangle { id: page; width: 640; height: 1136; color: "red" }
                      @
                      @
                      // main.cpp
                      #include <QGuiApplication>
                      #include <QQuickView>
                      #include <QString>
                      #if defined(Q_OS_IOS)
                      #include <QtPlugin>
                      Q_IMPORT_PLUGIN(qsqlite)
                      #include <QSqlDatabase>
                      #endif
                      int main(int argc, char *argv[]) {
                      QGuiApplication *app = new QGuiApplication(argc, argv);
                      // QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "xa_db");
                      QQuickView *view = new QQuickView;
                      view->setSource(QUrl("qrc:///main.qml"));
                      view->setResizeMode(QQuickView::SizeRootObjectToView);
                      view->show();
                      return app->exec();
                      }
                      @
                      @
                      <!-- Info.plist -->
                      <?xml version="1.0" encoding="UTF-8"?>
                      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
                      <plist version="1.0">
                      <dict>
                      <key>CFBundleName</key>
                      <string>sqlite_on_ios</string>
                      <key>CFBundleExecutable</key>
                      <string>sqlite_on_ios</string>
                      <key>CFBundleIconFile</key>
                      <string>sqlite_on_ios</string>
                      <key>CFBundlePackageType</key>
                      <string>APPL</string>
                      <key>CFBundleShortVersionString</key>
                      <string>1.0.0</string>
                      <key>CFBundleVersion</key>
                      <string>1.0.0</string>
                      <key>CFBundleIdentifier</key>
                      <string>www.sqlite_on_ios.com</string>
                      </dict>
                      </plist>
                      @

                      Xcode build results in the following error:
                      @
                      main.cpp:8:14: fatal error: 'QSqlDatabase' file not found
                      #include <QSqlDatabase>
                      ^
                      1 error generated.
                      @


                      The minitool builds/ runs in iOS Simulator if I comment lines 5-9 of main.cpp.

                      What is needed in addition to use sqlite on iOS?

                      Would be really great to get a hint! :-)

                      Viele Grüße aktuell aus Berlin ;-)
                      jraichouni

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        You are missing

                        @QT += sql@

                        in your pro file

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 0
                        • J
                          jraichouni last edited by

                          Alright, missed that and now the same error appears as I got it in my original project yesterday.

                          Xcode says:
                          @
                          Undefined symbols for architecture i386:
                          "qt_static_plugin_qsqlite()", referenced from:
                          StaticqsqlitePluginInstance::StaticqsqlitePluginInstance() in main.o
                          ld: symbol(s) not found for architecture i386
                          clang: error: linker command failed with exit code 1 (use -v to see invocation)
                          @
                          Does anything from my Qt (iOS) Installation (e.g. from plugin sqldrivers) need to be copied/ deployed into the build for iOS Simulator?

                          Or do I need to specify the -spec argument within the call of qmake because of that architecture error above?

                          1 Reply Last reply Reply Quote 0
                          • S
                            syfy323 last edited by

                            @ QStringList paths = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
                            QString dbFile = paths.first().append("/datastore.db");

                            QSqlDatabase *database = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"));
                            database->setDatabaseName( dbFile );@
                            

                            Add this to your .pro:
                            QT += sql
                            QTPLUGIN += qsqlite

                            As explained here (inclusing your cross post):
                            http://qt-project.org/forums/viewthread/36600/#156960
                            ... (by SGaist) using a pointer is not necessary.

                            1 Reply Last reply Reply Quote 1
                            • J
                              jraichouni last edited by

                              Tried it, and Xcode fails with below error. Did you try to build it for iOS Simulator?
                              @
                              Undefined symbols for architecture i386:
                              "qt_static_plugin_qsqlite()", referenced from:
                              StaticqsqlitePluginInstance::StaticqsqlitePluginInstance() in main.o
                              ld: symbol(s) not found for architecture i386
                              clang: error: linker command failed with exit code 1 (use -v to see invocation)
                              @
                              Used as you proposed:
                              @

                              sqlite_on_ios.pro

                              TEMPLATE = app
                              QT += qml quick sql
                              QTPLUGIN += qsqlite
                              QMAKE_INFO_PLIST += Info.plist
                              SOURCES += main.cpp
                              RESOURCES += main.qrc
                              cache()
                              @

                              My main.cpp:
                              @
                              // main.cpp
                              #include <QGuiApplication>
                              #include <QQuickView>
                              #include <QString>
                              #include <QtPlugin>

                              Q_IMPORT_PLUGIN(qsqlite)
                              #include <QSqlDatabase>

                              int main(int argc, char *argv[]) {
                              QGuiApplication *app = new QGuiApplication(argc, argv);
                              // QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "xa_db");
                              QQuickView *view = new QQuickView;
                              view->setSource(QUrl("qrc:///main.qml"));
                              view->setResizeMode(QQuickView::SizeRootObjectToView);
                              view->show();
                              return app->exec();
                              }
                              @

                              1 Reply Last reply Reply Quote 0
                              • S
                                syfy323 last edited by

                                I am using a recent version of Qt 5.2.0-dev snapshot (in the title you are writing you are using 5.1).
                                For iOS development you should stick to 5.2.0 instead of < 5.2.0.

                                edit: yes, I did - works for Mac, iOS Sim and on my iPhone.

                                1 Reply Last reply Reply Quote 0
                                • J
                                  jraichouni last edited by

                                  I am using "Qt 5.2.0 (official release)":http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-mac-opensource-5.2.0-ios-x86_64-offline.dmg

                                  I did not create the thread.

                                  A very short but complete mini project .pro file & main.cpp would help.

                                  I mean an example, which runs at your computer. I would launch qmake only to get the .xcodeproject directory to test that.

                                  1 Reply Last reply Reply Quote 0
                                  • S
                                    syfy323 last edited by

                                    [quote author="jraichouni" date="1389032658"]I am using "Qt 5.2.0 (official release)":http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-mac-opensource-5.2.0-ios-x86_64-offline.dmg

                                    I did not create the thread.[/quote]

                                    Oh, sorry.

                                    drop this from your file:
                                    Q_IMPORT_PLUGIN(qsqlite)

                                    edit for your edit:

                                    [quote author="jraichouni" date="1389032658"]
                                    A very short but complete mini project .pro file & main.cpp would help.

                                    I mean an example, which runs at your computer. I would launch qmake only to get the .xcodeproject directory to test that.[/quote]

                                    I already did - the code above works as your main() content.

                                    1 Reply Last reply Reply Quote 0
                                    • J
                                      jraichouni last edited by

                                      It runs!
                                      I am a bit confused, as the "Plug & paint example":http://qt-project.org/doc/qt-4.8/tools-plugandpaint.html uses that macro.

                                      But many thanks for your reply and help!!

                                      Really interesting would be to be able to use the SQLite Function "load_extension" which is omitted in Standard Qt build.

                                      1 Reply Last reply Reply Quote 0
                                      • S
                                        syfy323 last edited by

                                        [quote author="jraichouni" date="1389033119"]It runs!
                                        I am a bit confused, as the "Plug & paint example":http://qt-project.org/doc/qt-4.8/tools-plugandpaint.html uses that macro.

                                        But many thanks for your reply and help!![/quote]

                                        You're welcome.

                                        1 Reply Last reply Reply Quote 0
                                        • M
                                          mac131 last edited by

                                          "A very short but complete mini project .pro file & main.cpp would help.
                                          I mean an example, which runs at your computer. I would launch qmake only to get the .xcodeproject directory to test that."

                                          I just start to use QT 5.2 (with iOS even more) a mini exemple project with all files would be great

                                          1 Reply Last reply Reply Quote 0
                                          • J
                                            jraichouni last edited by

                                            Hi!

                                            Take the example in the current thread.

                                            The important things to consider are:

                                            .pro file:
                                            @
                                            QT += sql
                                            ios:QTPLUGIN += qsqlite

                                            deploy the database file via something like:

                                            databases.files = ../../src/data/xp-apt.sqlite
                                            ios: databases.path = Documents
                                            macx: databases.path = Contents/Resources
                                            QMAKE_BUNDLE_DATA += databases

                                            note, that the path databases.files is relative to the cwd, in which

                                            the process qmake runs

                                            @

                                            The class implementing the initialisation/ access to the db needs to do the following for instance:
                                            @
                                            #include <QtSql>
                                            (...)

                                            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "some_name");
                                            QSqlDatabase db = QSqlDatabase::database("some_name", false);
                                            QString dbFilePath = "(...)";
                                            db.setDatabaseName(dbFilePath);
                                            db.open();
                                            QSqlQuery *q = new QSqlQuery(db);
                                            (...)
                                            @

                                            Hope that helps!

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post