Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为iOS的sqLite创建从上次插入到sqLite的json对象和数据库浏览器_Ios_Objective C_Json_Sqlite_Cocoa Touch - Fatal编程技术网

如何为iOS的sqLite创建从上次插入到sqLite的json对象和数据库浏览器

如何为iOS的sqLite创建从上次插入到sqLite的json对象和数据库浏览器,ios,objective-c,json,sqlite,cocoa-touch,Ios,Objective C,Json,Sqlite,Cocoa Touch,我有两个主要问题 第一个;我在iOS应用程序中使用的sqlite是否有数据库浏览器 第二个问题——大问题——有点复杂 -(BOOL)createDB{ NSString *docsDir; NSArray *dirPaths; // Get the documents directory dirPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask

我有两个主要问题

第一个;我在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方法,我称之为我的applicationIDbecome 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;

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

我想要的是这个

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

-(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;
}
我需要创建最后一个插入行,并将其设置为JSON格式,以便可以对其进行操作并将其写入后端服务器

我该怎么做

提前谢谢

切里斯

  • 关于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插件。我个人使用的是一个相对便宜的SQLite工具。你想用什么就用什么

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

    因此,假设您将有一些模型结构来捕获这个本地表的十三列中的内容。因此,在本地表中插入该数据,然后编写一个不同的例程,获取该模型数据并创建请求,将该数据发布到服务器

    您需要确定web服务API的外观以及发布方式(例如,
    NSURLConnection
    NSURLSession
    (适用于iOS 7及更高版本),但这似乎远远超出了此问题的范围

  • 一些不相关的观察结果:

  • 如果您使用
    sqlite3\u 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\u exec

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

    此外,如果语句成功,
    getUserFirstName
    将立即返回。因此,它并没有释放与
    sqlite3\u prepare\u v2
    相关的内存(您应该通过
    sqlite3\u finalize
    ,而不是
    sqlite3\u 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\u bind\u null
    ,而不是
    sqlite3\u bind\u text

  • 你只插入用户名对我来说没有什么意义。您可能希望一次插入所有列值

  • 编写SQLite代码时,您可能需要考虑使用SQLite C API周围的瘦Objto-C包装器,这大大简化了您的生活。当您处理第3步时,为十三列中的每一列执行

    sqlite3\u bind\u XXX
    调用,我想您将真正开始欣赏类似FMDB的功能


  • 如果这是您的第一个web服务项目,我可能建议您查看Wenderlich的和。后者使用了现在已经过时的ASIHTTPRequest(现在很多人更喜欢AFNetworking),但它可能仍然是对iOS应用程序和后端MySQL数据库之间交配仪式的一个很好的介绍。首先,老兄,我非常感谢你给出了这么长的答案。现在大多数用户只想快速获得+1票,但你老兄,你的目的当然是为了帮助op——在这个例子中是我——写你的笔记,是的,这将是我的第一次连接试用。是的,我将写所有13列,然后用json将其写入mysql,你能指出我正在做的更多错误点吗?例如,我不确定是否要删除我将发送到mysql的内容。我应该将它们保存在sqlite中吗?或者是否有任何系统会让我知道传递成功。再次非常感谢:)保存发送到服务器的内容的本地副本通常是合理的,以便在需要时要再次向用户显示它,您不必从服务器重新检索它。更重要的是,您希望编写web服务,以便在成功接收数据并将其存储在MySQL数据库中时提供确认。让web服务使用JSON响应可以使客户端应用程序更容易解析响应并确认成功。这并不是自动发生的:你必须自己编写web服务来提供成功的确认。你能告诉我关于这个sqlite包装器的情况吗,我应该在哪里使用它?另外,我的连接是片面的。我不会从服务器接收数据,我只会发送推送通知。当使用sqlite C界面时,很容易泄漏内存(如您的问题所示),而我