ios - 使用 NSURLConnection 返回超大字符串的正确方法是什么?

标签 ios string csv ios7 nsurlconnection

我要连接的 URL 是一个以 CSV 格式输出大量数据的 php 文件。

现在一切正常,我没有收到任何使用 NSURLConnection 的错误。但是,在使用 connectionDidFinishLoading 时,我没有收到所有数据。我将数据附加到 didReceiveData 中。有时我得到的数据比其他人多,所以连接似乎没有保持足够长的时间来完成获取数据。

使用 NSURLConnection 获取超大字符串的正确方法是什么?

这是我使用的代码:

- (void)checkDatabaseUpdate_Places
{

    NSString *post =
    [[NSString alloc] initWithFormat:@"some_parameters_here"];

    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

    NSURL *url = [NSURL URLWithString:@"site_url_here"];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPBody:postData];
    [theRequest setTimeoutInterval:30];
    [theRequest setHTTPShouldHandleCookies:NO];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if( theConnection )
    {
        placesTableData = [[NSMutableData alloc] init];
        placesTableVerification = @"getting data";
    }
    else
    {
        NSLog(@"Bad Connection for Places");
    }

}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    long long dataSize = [response expectedContentLength];
    NSLog(@"expected data size: %lld", dataSize);

    if ([placesTableVerification isEqualToString:@"getting data"]) {
        [placesTableData setLength: 0];
    }
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if ([placesTableVerification isEqualToString:@"getting data"]) {
        [placesTableData appendData:data];
        placesTableVerification = @"got data";
    }

}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"connectionDidFailWithError %@",error.description);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Defaults Could Not Load" message:@"There was an error loading your defaults. Make sure your device has an active internet connection." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];

}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    //Database Setup
    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:
                                      @"database_name.db"]];

    NSLog(@"%@",_databasePath);

    NSFileManager *filemgr = [NSFileManager defaultManager];

    if ([filemgr fileExistsAtPath: _databasePath ] == NO)
    {
        const char *dbpath = [_databasePath UTF8String];

        if (sqlite3_open(dbpath, &_database) == SQLITE_OK)
        {
            //do nothing
        } else {
            NSLog(@"Failed to open database");
        }
    }

    const char *dbpath = [_databasePath UTF8String];
    sqlite3_stmt    *statement;
    //start Places Table Update
    if ([placesTableVerification isEqualToString:@"got data"]) {

        NSString *returnedData = [[NSString alloc] initWithBytes: [placesTableData mutableBytes] length:[placesTableData length] encoding:NSUTF8StringEncoding];

        NSLog(@"%lu -- %@",(unsigned long)[placesTableData length],returnedData);


        if (sqlite3_open(dbpath, &_database) == SQLITE_OK)
        {

            NSArray *tempArray = [[NSArray alloc] initWithArray:[returnedData componentsSeparatedByString:@"~~"]];

            NSString *tempItems = [[NSString alloc] init];

            for (tempItems in tempArray) {

                NSArray *itemArray = [[NSArray alloc] init];
                itemArray = [tempItems componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"|"]];

                NSMutableString *loadDB = [[NSMutableString alloc] initWithFormat:@"INSERT OR REPLACE INTO PLACES (ID,NAME,TYPE,CATEGORY,LATITUDE,LONGITUDE,CHAMBER_PRIMARY_CATEGORY,CHAMBER_SECONDARY_CATEGORY,INFORMATION,PHONE,FAX,EMAIL,WEBSITE,PHYSICAL_ADDRESS,MAILING_ADDRESS,START_DATE,STOP_DATE,HOTSPOT_FACTOR,MODIFIED) VALUES ("];

                int lastIndex = [itemArray count];
                int count = 0;

                NSString *tempItem = [[NSString alloc] init];

                for (tempItem in itemArray) {
                    count++;
                    NSString* string = [NSString stringWithFormat:@"%@" , tempItem];
                    if (count != lastIndex && string.length != 0) {
                        [loadDB appendString:@"\""];
                        [loadDB appendString:tempItem];
                        [loadDB appendString:@"\""];
                        [loadDB appendString:@","];
                    }
                    else if (count == lastIndex && string.length != 0){
                        [loadDB appendString:@"\""];
                        [loadDB appendString:tempItem];
                        [loadDB appendString:@"\""];
                    }
                    else {
                        [loadDB appendString:@"\"\","];
                    }


                }
                //end for

                loadDB = [[loadDB substringWithRange:NSMakeRange(0, loadDB.length)] mutableCopy];

                [loadDB appendString:@")"];

                //NSLog(loadDB);

                const char *errMsg;

                const char *insert_stmt = [loadDB UTF8String];

                sqlite3_prepare_v2(_database, insert_stmt,
                                   -1, &statement, &errMsg);
                NSLog(@"%s",insert_stmt);
                NSLog(@"%d",sqlite3_prepare_v2(_database, insert_stmt,
                                               -1, &statement, &errMsg));
                NSLog(@"%s",sqlite3_errmsg(_database));

                if (sqlite3_step(statement) == SQLITE_DONE)
                {
                    NSLog(@"Places Table Updated");
                }
                //end if
                else {
                    NSLog(@"Places Table Failed To Update");
                    //NSLog(@"%d",sqlite3_step(statement));
                }
                //end else

                sqlite3_finalize(statement);

                NSLog(@"%s",sqlite3_errmsg(_database));

            }
            //end for

        }
        //end if

        sqlite3_close(_the_kearney_app_database);

        [startupProgress setProgress:0.3 animated:YES];

    }
    //end Places Table Update

}

如果您能就我可能无法从服务器获得完整输出的原因提供任何帮助,我们将不胜感激。

解决方案

- (void)checkDatabaseUpdate_Places
{

    NSString *post =
    [[NSString alloc] initWithFormat:@"some_parameters_here"];

    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

    NSURL *url = [NSURL URLWithString:@"site_url_here"];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPBody:postData];
    [theRequest setTimeoutInterval:30];
    [theRequest setHTTPShouldHandleCookies:NO];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if( theConnection )
    {
        placesTableData = [[NSMutableData alloc] init];
        placesTableVerification = @"getting data";
    }
    else
    {
        NSLog(@"Bad Connection for Places");
    }

}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    long long dataSize = [response expectedContentLength];
    NSLog(@"expected data size: %lld", dataSize);

    if ([placesTableVerification isEqualToString:@"getting data"]) {
        [placesTableData setLength: 0];
    }
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if ([placesTableVerification isEqualToString:@"getting data"]) {
        [placesTableData appendData:data];
    }

}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"connectionDidFailWithError %@",error.description);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Defaults Could Not Load" message:@"There was an error loading your defaults. Make sure your device has an active internet connection." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];

}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    //Database Setup
    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:
                                      @"database_name.db"]];

    NSLog(@"%@",_databasePath);

    NSFileManager *filemgr = [NSFileManager defaultManager];

    if ([filemgr fileExistsAtPath: _databasePath ] == NO)
    {
        const char *dbpath = [_databasePath UTF8String];

        if (sqlite3_open(dbpath, &_database) == SQLITE_OK)
        {
            //do nothing
        } else {
            NSLog(@"Failed to open database");
        }
    }

    const char *dbpath = [_databasePath UTF8String];
    sqlite3_stmt    *statement;
    //start Places Table Update
    if ([placesTableVerification isEqualToString:@"getting data"]) {

        NSString *returnedData = [[NSString alloc] initWithBytes: [placesTableData mutableBytes] length:[placesTableData length] encoding:NSUTF8StringEncoding];

        NSLog(@"%lu -- %@",(unsigned long)[placesTableData length],returnedData);


        if (sqlite3_open(dbpath, &_database) == SQLITE_OK)
        {

            NSArray *tempArray = [[NSArray alloc] initWithArray:[returnedData componentsSeparatedByString:@"~~"]];

            NSString *tempItems = [[NSString alloc] init];

            for (tempItems in tempArray) {

                NSArray *itemArray = [[NSArray alloc] init];
                itemArray = [tempItems componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"|"]];

                NSMutableString *loadDB = [[NSMutableString alloc] initWithFormat:@"INSERT OR REPLACE INTO PLACES (ID,NAME,TYPE,CATEGORY,LATITUDE,LONGITUDE,CHAMBER_PRIMARY_CATEGORY,CHAMBER_SECONDARY_CATEGORY,INFORMATION,PHONE,FAX,EMAIL,WEBSITE,PHYSICAL_ADDRESS,MAILING_ADDRESS,START_DATE,STOP_DATE,HOTSPOT_FACTOR,MODIFIED) VALUES ("];

                int lastIndex = [itemArray count];
                int count = 0;

                NSString *tempItem = [[NSString alloc] init];

                for (tempItem in itemArray) {
                    count++;
                    NSString* string = [NSString stringWithFormat:@"%@" , tempItem];
                    if (count != lastIndex && string.length != 0) {
                        [loadDB appendString:@"\""];
                        [loadDB appendString:tempItem];
                        [loadDB appendString:@"\""];
                        [loadDB appendString:@","];
                    }
                    else if (count == lastIndex && string.length != 0){
                        [loadDB appendString:@"\""];
                        [loadDB appendString:tempItem];
                        [loadDB appendString:@"\""];
                    }
                    else {
                        [loadDB appendString:@"\"\","];
                    }


                }
                //end for

                loadDB = [[loadDB substringWithRange:NSMakeRange(0, loadDB.length)] mutableCopy];

                [loadDB appendString:@")"];

                //NSLog(loadDB);

                const char *errMsg;

                const char *insert_stmt = [loadDB UTF8String];

                sqlite3_prepare_v2(_database, insert_stmt,
                                   -1, &statement, &errMsg);
                NSLog(@"%s",insert_stmt);
                NSLog(@"%d",sqlite3_prepare_v2(_database, insert_stmt,
                                               -1, &statement, &errMsg));
                NSLog(@"%s",sqlite3_errmsg(_database));

                if (sqlite3_step(statement) == SQLITE_DONE)
                {
                    NSLog(@"Places Table Updated");
                }
                //end if
                else {
                    NSLog(@"Places Table Failed To Update");
                    //NSLog(@"%d",sqlite3_step(statement));
                }
                //end else

                sqlite3_finalize(statement);

                NSLog(@"%s",sqlite3_errmsg(_database));

            }
            //end for

        }
        //end if

        sqlite3_close(_the_kearney_app_database);

        [startupProgress setProgress:0.3 animated:YES];

    }
    //end Places Table Update

}

最佳答案

对于长数据,可以得到多个didReceiveData:回调。所以你必须追加所有这些,而不是在第一个之后停止。

来自documentation :

The delegate should concatenate the contents of each data object delivered to build up the complete data for a URL load.

关于ios - 使用 NSURLConnection 返回超大字符串的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21688389/

相关文章:

javascript - 检查字符串是否由所有唯一字符组成——JavaScript 中的不等于运算符

IOS COCOAPOD 及源码

ios - 我可以使用网络语言(HTML - CSS - jQuery)创建 iphone 应用程序 (IOS) 吗?

ios - 将 NSDate 设置为特定时间

ios - 通过过滤一些值从现有字典创建新字典

python - 如何检查 issubset 中以逗号分隔的整个单词?

c - 无法检查 C 中 argv[] 中的第二个字符

c# - 如何使用 .net 读取包含 2900 万行数据的巨大 CSV 文件

python - 什么是多维字典?

python - Pandas:读取文件的头部和中间部分