2

您好我正在尝试将 NSMutable 转换为 JSON 字符串,这是我的代码:

-(NSString *) buildFeedback {
    sqlite3_stmt *statement;
    sqlite3 *notificationDB;
    NSString *result = @"";
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [path objectAtIndex:0];
    NSString *dbPathString = [docPath stringByAppendingPathComponent:@"feedbacks.db"];

    if (sqlite3_open([dbPathString UTF8String], &notificationDB)==SQLITE_OK) {

        NSString *querySql = [NSString stringWithFormat:@"SELECT * FROM FEEDBACKS"];
        const char* query_sql = [querySql UTF8String];

        if (sqlite3_prepare(notificationDB, query_sql, -1, &statement, NULL)==SQLITE_OK) {
            while (sqlite3_step(statement)==SQLITE_ROW) {
                NSString *feedbackText = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
                NSMutableDictionary *feedback = [NSMutableDictionary dictionary];
                [feedback setObject:feedbackText forKey:@"content"];
                NSMutableDictionary *feedbacks = [NSMutableDictionary dictionary];
                [feedbacks setObject:feedback forKey:@"feedback"];



                NSError *error;
                NSData *jsonData = [NSJSONSerialization dataWithJSONObject:feedbacks
                                                                   options:0
                                                                     error:&error];

                if (! jsonData) {
                    NSLog(@"Got an error: %@", error);
                } else {
                     if ([result length])
                      result = [result stringByAppendingString:@","];

                    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                    result = [result stringByAppendingString:jsonString];
                }

            }
        }
    }
    sqlite3_close(notificationDB);
    return result;

}

在我的 Rails 服务器中,我得到了这个:

参数:{"feedbacks"=>"{\"feedback\":{\"content\":\"X<

我的问题是我如何在没有转义符(\“)的情况下做一个真正的 json 字符串。

4

1 回答 1

0

您的例程正在创建一个NSDictionary带有键的feedback(并且您将content字典放在其下方),制作一个字符串,并将其附加到结果中。然后,您似乎正在使用它并feedbacks使用该字符串作为键的对象制作字典。

相反,您应该返回NSData, 并让您的while循环将对象添加到 a NSMutableArray,您在循环结束时对其进行编码。


我会建议一些事情:

  1. 如果您的sqlite3呼叫失败,请检查sqlite3_errmsg.

  2. sqlite3_finalize当您完成对结果的迭代时,不要忘记做。

  3. 如果打开失败,您仍在尝试关闭数据库;移动块sqlite3_closeif成功打开。

  4. 将 JSON 创建移出while循环。

  5. 使用 aNSMutableArray而不是NSMutableDictionaryfor feedbacks(并将其声明移出while循环)。

因此:

-(NSData *) buildFeedback
{
    sqlite3_stmt *statement;
    sqlite3 *notificationDB;
    NSData *jsonData = nil;
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [path objectAtIndex:0];
    NSString *dbPathString = [docPath stringByAppendingPathComponent:@"feedbacks.db"];

    if (sqlite3_open([dbPathString UTF8String], &notificationDB)==SQLITE_OK) {

        NSString *querySql = [NSString stringWithFormat:@"SELECT * FROM FEEDBACKS"];
        const char* query_sql = [querySql UTF8String];

        if (sqlite3_prepare(notificationDB, query_sql, -1, &statement, NULL)==SQLITE_OK) {

            NSMutableArray *feedbacks = [NSMutableArray array]; // move this outside the `for` loop and make array

            while (sqlite3_step(statement) == SQLITE_ROW) {
                NSString *feedbackText = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
                NSMutableDictionary *feedback = [NSMutableDictionary dictionary];
                [feedback setObject:feedbackText forKey:@"content"];
                [feedbacks addObject:feedback];
            }

            // move the JSON stuff outside of the loop

            NSError *error;
            jsonData = [NSJSONSerialization dataWithJSONObject:feedbacks
                                                       options:0
                                                         error:&error];

            if (!jsonData) {
                NSLog(@"Got an error: %@", error);
            } else {

                // if you want to look at this for diagnostic purposes, that's fine,
                // but this function should return the `NSData`

                NSLog(@"jsonString = %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
            }

            // don't forget to finalize

            sqlite3_finalize(statement);
        }
        else
        {
            NSLog (@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(notificationDB));
        }

        // this should go inside the "open" == SQLITE_OK block

        sqlite3_close(notificationDB);
    }
    else
    {
        NSLog(@"%s: sqlite3_open failed!", __FUNCTION__);
    }

    return jsonData;
}
于 2013-05-31T15:18:21.603 回答