2014-02-10 3 views
0

연결 대상 URL은 매우 많은 양의 데이터를 CSV 출력 형식으로 출력하는 PHP 파일입니다.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

'NSURLConnection'에 사용하는 init 메소드는 즉시 로딩을 시작하지만'placesTableData'는 아직 초기화되지 않았습니다. 'theConnection' 전에'placesTableData'를 초기화하면 어떻게 될까요? 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

다시 해줘서 고맙습니다. 내 코드가 각 데이터 객체의 내용을 연결하는 것으로 밝혀졌습니다. 그러나 didRecieveData 내 placesTableVerification을 변경하고 내 조건문이 더 이상 사실이 아닙니다. 이 답변은 제 문제를 바로 잡기위한 올바른 방향으로 나에게 지적했습니다. 해결책으로 내 질문을 업데이트하고 있습니다. – mcphersonjr

관련 문제