2014-02-10 5 views
0

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 

} 
+0

Метод 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 –

+0

Хороший вопрос. Я попробую это сейчас. – mcphersonjr

+0

@MikeD Тот же результат. Кажется, что соединение закрывается до того, как он загрузит все данные, а не то, что данные не будут достаточно быстро захвачены. Но я мог быть совершенно неправ. – mcphersonjr

ответ

4

С длинными данными, вы можете получить несколько didReceiveData: обратных вызовов. Поэтому вы должны добавить все из них, а не останавливаться после первого.

documentation От:

Делегат должен объединить содержимое каждого объекта данных, поставляемой для создания полной базы данных для URL нагрузки.

+0

Благодарим вас за это. Как оказалось, мой код объединяет содержимое каждого объекта данных. Тем не менее, я изменил свой placeTableVerification внутри didRecieveData, и мое условное утверждение больше не было правдой. Этот ответ указал мне в правильном направлении на исправление моей проблемы. Я обновляю свой вопрос с помощью решения. – mcphersonjr

Смежные вопросы