URL-адрес, к которому я подключаюсь, представляет собой php-файл, выводящий очень большой объем данных в виде вывода CSV.Каков правильный способ возврата лишней большой строки с использованием NSURLConnection?
В настоящее время все работает правильно, и я не получаю никаких ошибок с помощью 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
}
Метод init, который вы используете для 'NSURLConnection', начинает загрузку немедленно, но' placesTableData' еще не инициализирован. Что произойдет, если вы инициализируете 'placesTableData' перед' theConnection'? https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-BAJDDIDG –
Хороший вопрос. Я попробую это сейчас. – mcphersonjr
@MikeD Тот же результат. Кажется, что соединение закрывается до того, как он загрузит все данные, а не то, что данные не будут достаточно быстро захвачены. Но я мог быть совершенно неправ. – mcphersonjr