【问题标题】:how to create a json object from the last insert to sqLite AND a database browser for sqlite of iOS如何从最后一次插入到 sqLite 和 iOS 的 sqlite 的数据库浏览器中创建 json 对象
【发布时间】:2014-10-31 06:52:10
【问题描述】:

我有 2 个主要问题。

第一个;我在我的 iOS 应用程序中使用了 SQLite 的任何数据库浏览器吗?

第二个问题——大问题——有点复杂。

-(BOOL)createDB{
    NSString *docsDir;
    NSArray *dirPaths;
    // Get the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = dirPaths[0];
    // Build the path to the database file
    databasePath = [[NSString alloc] initWithString:
                    [docsDir stringByAppendingPathComponent: @"insider.db"]];
    BOOL isSuccess = YES;
    NSFileManager *filemgr = [NSFileManager defaultManager];
    if ([filemgr fileExistsAtPath: databasePath ] == NO)
    {
        const char *dbpath = [databasePath UTF8String];
        if (sqlite3_open(dbpath, &database) == SQLITE_OK)
        {

            char *errMsg;
            const char *sql_stmt =
            "create table if not exists userInfo (device_token text primary key, device_type text, carrier text, app_version text,os_version text, first_name text, last_name text,last_viewed_item text, last_added_item text, last_item_price_tag text, name_entered integer, login_screen integer, item_detailed_screen integer )";
            if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)
                != SQLITE_OK)
            {
                isSuccess = NO;
                NSLog(@"Failed to create table");
            }
            sqlite3_close(database);
            return  isSuccess;
        }
        else {
            isSuccess = NO;
            NSLog(@"Failed to open/create database");
        }
    }
    return isSuccess;
}

这是我的 createDB 方法,我称之为我的 applicationDIdBecome active,

我有几种方法可以获取将保存到我的数据库中的项目其中之一;

-(BOOL)getUserFirstName:(NSString *)firstName {


    NSLog(@"User's first name is this %@",firstName);


    const char *dbpath = [databasePath UTF8String];
    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {

        NSString *insertSQL = [NSString stringWithFormat:@"insert into userInfo (first_name) values (\"%@\")", firstName];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            return YES;
        }
        else {
            return NO;
        }
        sqlite3_reset(statement);
    }
    return NO;

}

我有很多这样的方法(对于我的 create table 语句中的每一列)

我想要的是这个;

我有一个使用 mysql 作为数据库的后端。

我需要创建最后一个插入行并将其设为 JSON 格式,以便我可以对其进行操作并将其写入我的后端服务器。

我该怎么做?

提前致谢。

干杯。

【问题讨论】:

标签: ios objective-c json sqlite cocoa-touch


【解决方案1】:
  1. 关于 SQLite 工具,数据库格式是跨平台的二进制兼容。因此,您可以在模拟器中运行应用程序,浏览到包含模拟器文件的文件夹(取决于 Xcode 版本:在 6 之前的 Xcode 版本中为 ~/Library/Application Support/iPhone Simulator,在 Xcode 6 中为 ~/Library/Developer/CoreSimulator/Devices)并打开数据库。如果您的Library 文件夹已隐藏,您可以从终端命令行chflags nohidden ~/Library 取消隐藏它。

    您可以使用 Mac OS X sqlite3 命令行应用程序。许多人使用免费的 Firefox SQLite Manager 插件。我个人使用Base,一个相对便宜的SQLite 工具。使用任何你想要的。

  2. 关于从 SQLite 检索结果并从中创建 JSON,最简单的方法是使用这些值构建一个 NSDictionary,然后您可以将其传递给 NSJSONSerialization 方法 dataWithJSONObject,该方法可以构建 JSON 主体请求。

    因此,大概您将拥有一些模型结构来捕获此本地表的 13 列中的内容。因此,将该数据插入本地表中,然后编写一个不同的例程来获取该模型数据并创建您对 POST 的请求到服务器。

    您需要确定您的 Web 服务 API 的外观以及您希望如何 POST 它(例如 NSURLConnectionNSURLSession(适用于 iOS 7 及更高版本)、AFNetworking 等) ,但这似乎远远超出了这个问题的范围。

一些不相关的观察:

  1. 如果您使用sqlite3_exec,为错误消息提供指向char * 的指针,请记住您有责任发布该错误消息。此外,您还可以记录该错误消息,以便知道它失败的原因:

    if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) {
        isSuccess = NO;
        NSLog(@"Failed to create table: %s", errMsg);
        sqlite3_free(errMsg);
    }
    

    有关详细信息,请参阅sqlite3_execdocumentation

  2. 我建议不要使用 stringWithFormat 来构建您的 INSERT 语句。始终在 SQL 中使用 ? 占位符,然后手动绑定值。

    另外,如果语句成功,getUserFirstName 会立即返回。所以,它不会释放与sqlite3_prepare_v2 相关的内存(你应该通过sqlite3_finalize 来完成,而不是sqlite3_reset)。它也没有关闭数据库。

    -(BOOL)insertUserFirstName:(NSString *)firstName
    {
        BOOL success = YES;
    
        const char *dbpath = [databasePath UTF8String];
        if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
            const char *insert_stmt = "insert into userInfo (first_name) values (?)";
    
            if (sqlite3_prepare_v2(database, insert_stmt, -1, &statement, NULL) != SQLITE_OK) {
                NSLog(@"prepare failure: %s", sqlite3_errmsg(database));
                sqlite3_close(database);
                return NO;
            }
    
            if (sqlite3_bind_text(statement, 1, [firstName UTF8String], -1, NULL) != SQLITE_OK) {
                success = NO;
                NSLog(@"bind 1 failure: %s", sqlite3_errmsg(database));
            } else if (sqlite3_step(statement) != SQLITE_DONE) {
                success = NO;
                NSLog(@"step failure: %s", sqlite3_errmsg(database));
            }
    
            sqlite3_finalize(statement);
            statement = NULL;
    
            sqlite3_close(database);
            database = NULL;
        }
    
        return success;
    }
    

    就个人而言,我什至建议不要在每次 SQLite 调用时打开和关闭数据库。但是如果你这样做了,请确保你平衡你的开放语句和关闭语句,就像上面一样。您可能还需要测试以确保 firstName 不是 nil(如果是,请调用 sqlite3_bind_null 而不是 sqlite3_bind_text)。

  3. 您只插入用户名对我来说不太合理。您可能希望一次插入所有列值。

  4. 在编写 SQLite 代码时,您可能需要考虑使用 FMDB,这是一个围绕 SQLite C API 的精简 Objective-C 包装器,它极大地简化了您的生活。当您完成第 3 步,为您的 13 列中的每一列执行 sqlite3_bind_XXX 调用时,我想您会真正开始体会到 FMDB 之类的强大功能。

【讨论】:

  • 好吧,首先,我非常感谢你这么长的回答。如今,大多数用户只是希望快速 +1 投票,但你伙计,你当然是为了帮助op-在这种情况下我-对于您的笔记,是的,这将是我的第一次连接尝试。是的,我将编写所有 13 列,而不是使其成为 json 以将其写入 mysql,您能否指出我正在做的更多错误点?例如,我不确定是否删除我将发送到 mysql 的内容。我应该将它们保存在 sqlite 中吗?或者是否有任何系统可以让我知道交付成功。再次感谢您 :)
  • 保留发送到服务器的本地副本通常是合理的,这样如果您需要再次将其呈现给用户,您就不必从服务器重新检索它.更重要的是,您希望编写 Web 服务,以便在成功接收数据并将其存储在 MySQL 数据库中时提供确认。让 Web 服务使用 JSON 响应进行响应,使客户端应用程序更容易解析响应并确认成功。这不会自动发生:您必须自己编写 Web 服务来提供成功确认。
  • 你能告诉我这个 sqlite 包装器,我应该在哪里以及如何使用它吗?另一件事,我的连接将是单边的。我不会从服务器接收数据,我只会发送推送通知.
  • 在使用SQLite C接口时,容易出现内存泄漏(由你的问题说明),比较麻烦。 FMDB 为基本的数据库交互提供了一个更简单的接口。谷歌“fmdb 教程”链接。重新发送您的“通知”,通常您想知道它是否成功(例如,通常是成功布尔值、数字错误代码,以及失败时的一些失败描述)。在没有确认的情况下,您如何知道您是否有服务器问题或用户是否有基本的连接问题?
  • 亲爱的 Rob,你能看看我的新问题stackoverflow.com/questions/25713002/…
猜你喜欢
  • 1970-01-01
  • 2013-05-25
  • 2023-03-15
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
  • 2012-05-22
相关资源
最近更新 更多