我连接的URL是一个php文件,以CSV输出的形式输出大量数据。
现在一切正常,我没有收到任何使用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
}
答案 0 :(得分:4)
使用长数据,您可以获得多个didReceiveData:
回调。所以你必须追加所有这些,而不是在第一个之后停止。
委托应该连接内容 传递的每个数据对象,以构建URL的完整数据 负荷。