Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. [iOS] SQLite does not save every times
Forum Update on Monday, May 27th 2025

[iOS] SQLite does not save every times

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
8 Posts 3 Posters 1.6k Views
  • 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.
  • V Offline
    V Offline
    Vi67
    wrote on 2 May 2017, 09:05 last edited by
    #1

    Hello,

    I'm making a mobile app on iOS and Android.
    Data are kept in memory with a SQLite DB.

    Data are saved nicely in Android, but not in iOS. Some times insert are not working.
    Do you have an idea where it comes from ?

    I open/close data base depend on application states :

    class ApplicationListener : public QObject
    {
        Q_OBJECT
    
    public:
        ApplicationListener(QObject *parent = 0) : QObject(parent)
        {
            DataBase::open();
            /*
            *   s_db = QSqlDatabase::addDatabase("QSQLITE");
            *   QString dbFile = Config::getWritableLocation() + "local.sqlite";
            *   s_db.setDatabaseName(dbFile);
            *   s_db.open();
            */
    
            QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
            QObject::connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(onApplicationQuit()));
        }
    
    public slots:
        void onApplicationStateChanged(Qt::ApplicationState state)
        {
            if (state == Qt::ApplicationActive) {
                DataBase::open();
            }
            else {
                DataBase::close();
                /*
                *   s_db.close();
                */
            }
        }
    
        void onApplicationQuit()
        {
            DataBase::close();
        }
    };
    
    T 1 Reply Last reply 2 May 2017, 09:08
    0
    • V Vi67
      2 May 2017, 09:05

      Hello,

      I'm making a mobile app on iOS and Android.
      Data are kept in memory with a SQLite DB.

      Data are saved nicely in Android, but not in iOS. Some times insert are not working.
      Do you have an idea where it comes from ?

      I open/close data base depend on application states :

      class ApplicationListener : public QObject
      {
          Q_OBJECT
      
      public:
          ApplicationListener(QObject *parent = 0) : QObject(parent)
          {
              DataBase::open();
              /*
              *   s_db = QSqlDatabase::addDatabase("QSQLITE");
              *   QString dbFile = Config::getWritableLocation() + "local.sqlite";
              *   s_db.setDatabaseName(dbFile);
              *   s_db.open();
              */
      
              QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
              QObject::connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(onApplicationQuit()));
          }
      
      public slots:
          void onApplicationStateChanged(Qt::ApplicationState state)
          {
              if (state == Qt::ApplicationActive) {
                  DataBase::open();
              }
              else {
                  DataBase::close();
                  /*
                  *   s_db.close();
                  */
              }
          }
      
          void onApplicationQuit()
          {
              DataBase::close();
          }
      };
      
      T Offline
      T Offline
      the_
      wrote on 2 May 2017, 09:08 last edited by the_ 5 Feb 2017, 09:09
      #2

      @Vi67
      Where in your code do you write into the database?
      In the code sniplet only the open/close calls are shown. Is the app in the correct state when you try to exec an insert?
      What exactly is DataBase ?

      -- No support in PM --

      1 Reply Last reply
      0
      • V Offline
        V Offline
        Vi67
        wrote on 2 May 2017, 09:17 last edited by
        #3

        Inserts are made in a class extends from Table class, there is a part :

        QSqlQuery Table::insert(const QStringList& keys, const QVariantList& values)
        {
            QString keysAsParam = getKeysString(true, false, false, keys);
            QString keysNoParam = getKeysString(false, false, false, keys);
        
            QSqlQuery query = QSqlQuery(DataBase::getDB());
            query.prepare("INSERT INTO " + m_name + " (" + keysNoParam + ") VALUES (" + keysAsParam + ");");
        
            for (int i = 0; i < values.size(); ++i) {
                query.bindValue(":"+keys.at(i), values.at(i));
            }
        
            return query;
        }
        
        QString Table::getKeysString(bool asParams, bool withTypes, bool withValues, QStringList keys)
        {
            if (keys == QStringList())
                keys = m_keys;
        
            QString keysString = QString();
        
            for (int i=0 ; i<keys.size() ; ++i) {
                if (asParams)
                    keysString += ":";
        
                keysString += keys[i];
        
                if (withValues)
                    keysString += " = :" + keys[i];
        
                if (withTypes)
                    keysString += " " + m_types[i];
        
                if (i < keys.size()-1)
                    keysString += ",";
            }
        
            return keysString;
        }
        

        There is DataBase class :

        void DataBase::open()
        {
            s_db = QSqlDatabase::addDatabase("QSQLITE");
        
            QString dbFile = Config::getWritableLocation() + "local.sqlite";
        
            qDebug() << "dbFile : " << dbFile;
            
            s_db.setDatabaseName(dbFile);
        
            if(!s_db.open()) {
                qDebug() << "Failed to connect local data base, details : " << s_db.lastError().driverText();
                return;
            }
        }
        
        void DataBase::close()
        {
            s_db.close();
        }
        
        1 Reply Last reply
        0
        • shavS Offline
          shavS Offline
          shav
          wrote on 2 May 2017, 10:14 last edited by
          #4

          @Vi67 Are you saves your database file as a application resource or your app created it?

          Mac OS and iOS Developer

          1 Reply Last reply
          0
          • V Offline
            V Offline
            Vi67
            wrote on 2 May 2017, 12:40 last edited by
            #5

            @shav I put the file in DocumentsLocation

            QString Config::getWritableLocation() {
            #ifdef Q_OS_IOS
                return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/";
            #else
                return "";
            #endif
            }
            
            T 1 Reply Last reply 2 May 2017, 13:04
            0
            • shavS Offline
              shavS Offline
              shav
              wrote on 2 May 2017, 12:58 last edited by
              #6

              So your application created database in Documents folder of application, right? If so I think you need to check SQL query. Try to print full SQL query to debug console. Maybe some of data is incorrect.

              Mac OS and iOS Developer

              1 Reply Last reply
              0
              • V Vi67
                2 May 2017, 12:40

                @shav I put the file in DocumentsLocation

                QString Config::getWritableLocation() {
                #ifdef Q_OS_IOS
                    return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/";
                #else
                    return "";
                #endif
                }
                
                T Offline
                T Offline
                the_
                wrote on 2 May 2017, 13:04 last edited by
                #7

                @Vi67

                • Whats the code of your query execution? The previos sniplet only showed that you prepare the query and return it but no exec.
                • Can you check if you get any error at query.exec() ?

                -- No support in PM --

                1 Reply Last reply
                0
                • V Offline
                  V Offline
                  Vi67
                  wrote on 2 May 2017, 13:49 last edited by Vi67 5 Feb 2017, 13:51
                  #8

                  @shav @the_ Thanks for your both answers.
                  You're right, now I need to know the errors/log when it happens. But it happens so rarely, never when the device is connected to computer for primary tests. I need to implement a way to send logs to the server. It looks like it happens when the application is kept in background from a long time.

                  @the_
                  There is the main query execution. This part do a lot for synchronization system between local data and server data.

                  bool Table::setOne(QVariantMap object, QVariant previousId)
                  {
                      if (!object.contains("_id")) {
                          if (Config::debug)
                              qDebug() << "!Warning! setOne - object do not have an _id";
                          return false;
                      }
                  
                      object.detach();
                  
                      QMapIterator<QString, QVariant> it(object);
                      while (it.hasNext()) {
                          it.next();
                          if (!m_keys.contains(it.key()))
                             object.remove(it.key());
                      }
                  
                      // if object doesn't have a temporary local id
                      if (previousId == QVariant()) {
                  
                          QSqlQuery selectQ = select("*", "_id = :_id", {object.value("_id")});
                          selectQ.exec();
                  
                          // if exists -> update
                          if (selectQ.next()) {
                              QVariant idValue = object.value("_id");
                              object.remove("_id");
                  
                              QSqlQuery updateQ = update(object.keys(), object.values(), "_id = :_id", {idValue});
                              bool executed = updateQ.exec();
                              if (Config::debug) {
                                  qDebug() << "setOne-!Id-Update : " << executed << updateQ.lastQuery();
                                  qDebug() << "setOne-!Id-Update : " << updateQ.lastError();
                              }
                              return executed;
                          }
                          // if !exists -> insert
                          else {
                              QSqlQuery insertQ = insert(object.keys(), object.values());
                              bool executed = insertQ.exec();
                              if (Config::debug) {
                                  qDebug() << "setOne-!Id-Insert : " << executed << insertQ.lastQuery();
                                  qDebug() << "setOne-!Id-Insert : " << insertQ.lastError();
                              }
                              return executed;
                          }
                  
                      }
                      // if object has a temporary local id
                      else {
                  
                          // remove previous object
                          QSqlQuery removeQ = remove("_id = :_id", {previousId});
                          bool removeExecuted = removeQ.exec();
                          if (Config::debug) {
                              qDebug() << "setOne-Id-Remove : " << removeExecuted << removeQ.lastQuery();
                              qDebug() << "setOne-Id-Remove : " << removeQ.lastError();
                          }
                  
                          // replace it by the one from server
                          QSqlQuery insertQ = insert(object.keys(), object.values());
                          bool insertExecuted = insertQ.exec();
                          if (Config::debug) {
                              qDebug() << "setOne-Id-Insert : " << insertExecuted << insertQ.lastQuery();
                              qDebug() << "setOne-Id-Insert : " << insertQ.lastError();
                          }
                  
                          return removeExecuted && insertExecuted;
                  
                      }
                  }
                  
                  1 Reply Last reply
                  0

                  1/8

                  2 May 2017, 09:05

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved