FMDB Результат преобразования таблицы в объект JSON с соблюдением порядка столбцов.

РЕДАКТИРОВАТЬ: НОВЫЙ ВОПРОС ВНИЗУ. Я получил все строки, я был неправ. Я пытаюсь получить результаты SQL-запроса и поместить их в объект json для отправки на мой сервер, чтобы выполнить дополнительную работу с данными. Сейчас мой код возвращает только 1 строку данных. Может кто-нибудь увидеть вопиющие ошибки? СТОРОНА IOS

- (void)sendLogin
{
NSError *jsonError;
NSData *requestdata;
//get login
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [docPaths objectAtIndex:0];
NSString *dbPath = [documentsDir   stringByAppendingPathComponent:@"tar.sqlite"];

FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
[database open];
FMResultSet *Loginresults = [database executeQuery:@"SELECT * FROM surveys"];
NSMutableArray *results = [NSMutableArray array];
while ([Loginresults next]) {
    [results addObject:[Loginresults resultDictionary]];

    requestdata = [NSJSONSerialization dataWithJSONObject:results options:0 error:&jsonError];
}

[database close];




NSURL *url = [NSURL URLWithString:@"http://server/insert.php"];

NSMutableURLRequest *request;
request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", [requestdata length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:requestdata];

//this kicks off the request asynchronously
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

СТОРОНА PHP

<?php
$foo = file_get_contents("php://input");

var_dump(json_decode($foo, true));

?>

Результаты этого

finish requesting: array(1) {
[0]=>
array(7) {
["desc"]=>
string(13) "matt the best"
["creator"]=>
string(7) "eric jr"
["synch"]=>
NULL
["name"]=>
string(4) "matt"
["sid"]=>
string(1) "1"
["datetime"]=>
string(3) "now"
["pid"]=>
string(1) "1"
}
}

Также я заметил, что мои результаты для этой таблицы не в правильном порядке. Это работает как задумано? Есть ли способ заказать это, чтобы оно соответствовало порядку столбцов?


person William Brasky    schedule 19.11.2013    source источник


Ответы (2)


Ok. Позвольте мне объяснить решение. Как вы сказали в комментарии, вы используете библиотеку во всем приложении.

Итак, я думаю, что лучшим решением вашей проблемы будет создание OrderedDictionary из CocoaWithLove< /а>. OrderedDictionary содержит NSMutableDictionary и NSMutableArray для ключей внутри него, чтобы отслеживать порядок ключей.

Вы можете создать категорию FMResultSet:

FMResultSet+OrderedDict.h

#import <Foundation/Foundation.h>
#import "FMResultSet.h"
#import "OrderedDictionary.h"
@interface FMResultSet(OrderedDict)
- (OrderedDictionary*)resultOrderDictionary;
@end

FMResultSet+OrderedDict.m

#import "FMResultSet+OrderedDict.h"
#import "OrderedDictionary.h"
#import "FMDatabase.h"

@implementation FMResultSet(OrderedDict)

- (OrderedDictionary*)resultOrderDictionary {

    NSUInteger num_cols = (NSUInteger)sqlite3_data_count([_statement statement]);

    if (num_cols > 0) {
        OrderedDictionary *dict = [OrderedDictionary dictionaryWithCapacity:num_cols];

        int columnCount = sqlite3_column_count([_statement statement]);

        int columnIdx = 0;
        for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {

            NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)];
            id objectValue = [self objectForColumnIndex:columnIdx];
            [dict setObject:objectValue forKey:columnName];
        }

        return dict;
    }
    else {
        NSLog(@"Warning: There seem to be no columns in this set.");
    }

    return nil;
}

@end

И в вашем коде сделайте так:

NSMutableArray *results = [NSMutableArray array];
    while ([Loginresults next]) {
        [results addObject:[Loginresults resultOrderDictionary]];
    }
    requestdata = [NSJSONSerialization dataWithJSONObject:results options:0 error:&jsonError];

Если хотите, я могу загрузить свой проектный тест на github.

РЕДАКТИРОВАТЬ: теперь загружается код.

person dcorbatta    schedule 20.11.2013
comment
Здорово!! Спасибо! Я попробую это и другое решение и отпишусь, чтобы вы знали, что я сделал. - person William Brasky; 20.11.2013
comment
Пожалуйста. если вы хотите, вы можете изменить название вопроса, чтобы другие люди с той же проблемой могли найти ответ. - person dcorbatta; 20.11.2013

Я не знаком с FMDatabase. Но я думаю, что ваша проблема в операторе while:

FMResultSet *Loginresults = [database executeQuery:@"SELECT * FROM surveys"];
NSMutableArray *results = [NSMutableArray array];
while ([Loginresults next]) {
    [results addObject:[Loginresults resultDictionary]];

    requestdata = [NSJSONSerialization dataWithJSONObject:results options:0 error:&jsonError];
}

Вы перезаписываете переменную: requestdata с каждым результатом.

Возможно, если вам нужно изменить код для этого:

FMResultSet *Loginresults = [database executeQuery:@"SELECT * FROM surveys"];
NSMutableArray *results = [NSMutableArray array];
while ([Loginresults next]) 
{
    [results addObject:[Loginresults resultDictionary]];
}
requestdata = [NSJSONSerialization dataWithJSONObject:results options:0 error:&jsonError];
person dcorbatta    schedule 19.11.2013
comment
У вас есть расширение FMResultSet? Я вижу github.com/ccgus/fmdb и не вижу метод resultDictionary. - person dcorbatta; 20.11.2013
comment
Привет, я следую этому руководству, brianjcoleman.com/ и также сослаться на этот вопрос stackoverflow.com/questions/9405059 / - person William Brasky; 20.11.2013
comment
Не могли бы вы прислать мне пример проекта? - person dcorbatta; 20.11.2013
comment
Я проверил ваш код, я создаю таблицу с 2 строками, и php показывает 2 строки. Сколько у вас рядов? Возможно проблема с размером результатов. - person dcorbatta; 20.11.2013
comment
Извините, я отредактировал свой вопрос. Он показывает правильное количество строк, которые я сейчас борюсь с порядком. - person William Brasky; 20.11.2013
comment
ОЙ! хорошо.. Но согласны ли вы со мной, что строка requestdata = ... должна выходить за пределы оператора while. Проблема с порядком в том, что: Это словарь, значит, это хеш-таблица. Посмотрим, смогу ли я найти быстрое решение. Вы часто используете библиотеку FMDB? - person dcorbatta; 20.11.2013
comment
Мне нужно попасть в лабораторию утром, у меня здесь нет Mac. Я попробую это тогда. Вы ответили еще на один из моих вопросов о размещении файла SQLite, этот вопрос был альтернативой этому. Я бы предпочел отправить файл sqlite и внести в него изменения php, чем это, поэтому я надеюсь, что это сработает. И да, я использую FMDB во всем приложении. - person William Brasky; 20.11.2013