2014-02-10 31 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

您用于NSURLConnection的init方法立即开始加载,但placesTableData尚未初始化。 “连接”之前初始化'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

相关问题