0

我从 2 天开始就卡住了,我想显示下载进度条。我将 json 邮寄到服务器,作为响应服务器向我发送视频数据。为了显示进度条,我编写了一些逻辑代码,例如

didreceivedata方法中,ASIhttep我将接收数据附加到全局NSmutabledata,在请求完成方法中,我将该全局Nsmutalbedata写入文件。但文件是空白的,它不会存储到文件中。

我知道 ASIHttprequest 是旧库,但每个人都建议我使用 AFnetworking,但我不想更改代码,因为这需要很长时间,而且我必须再次阅读文档。

任何人都可以帮助我如何附加数据并在下载完成后将附加的数据写入文件?

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[[NSURL alloc] initWithString:@"http://testing.io/dev.php/video/verifyReceipt"]];

    [request setDidReceiveDataSelector:@selector(request:didReceiveData:)]; 
    [request setPostValue:resultAsString forKey:@"verify"];
    [request setDidFinishSelector:@selector(requestDone:)];
    [request setTimeOutSeconds:120];
    [request setDelegate:self];
    [request setNumberOfTimesToRetryOnTimeout:2];
    [request setDownloadProgressDelegate:progressBar];
    request.showAccurateProgress = YES;

    [request startSynchronous];
    }
    -(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
    {
          [videoData appendData:data];
          NSLog(@"data is %@",data);
    }

   - (void)requestDone:(ASIHTTPRequest *)request
   {
    //[MBProgressHUD hideHUDForView:self.view animated:YES];

    // SAVED PDF PATH
    // Get the Document directory
      NSString *documentDirectory =   [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
     // Add your filename to the directory to create your saved pdf location
    NSString* movLocation = [documentDirectory stringByAppendingPathComponent:[fileName stringByAppendingString:@".mov"]];

    if(request.responseStatusCode==200)
    {
        [videoData writeToFile:movLocation atomically:NO];
        NSLog(@"in request done sucsessfully downlaod and store in database %d",request.responseStatusCode);
        [DBHelper savePurchaseId:fileName];
        [self movieReceived];
    }
    else
    {        
        NSLog(@"in request downlaod and store in database failed %@",request.responseHeaders);

    }
 }
4

2 回答 2

0

最好对这样的任务使用异步请求。您可以使用相同的ASIHTTPRequest类,但使用块方法。尝试编写类似这样的代码:

-(void) verifyReceipt {
    NSURL *theURL = [NSURL URLWithString:@"http://testing.io/dev.php/video/verifyReceipt"];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
[theRequest setHTTPMethod:@"POST"];

    NSString *param1 = [self getParam1]; // getParam1 - some method to get useful data for request's body
    NSNumber *param2 = [self getParam2];
    NSString *postString = [NSString stringWithFormat:@"param1=%@&param2=%@", param1, param2];

    [theRequest setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:theRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         if ([data length] > 0 && error == nil) {
             //[delegate receivedData:data]; // - if you want to notify some delegate about data arrival
             NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
             NSString *filePath = [NSString stringWithFormat:@"%@/fileArrived.ext", rootPath];

             //try to access that local file for writing to it...
             NSFileHandle *hFile = [NSFileHandle fileHandleForWritingAtPath:filePath];
             //did we succeed in opening the existing file?
             if (!hFile)
             {   //nope->create that file!
                 [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
                 //try to open it again...
                 hFile = [NSFileHandle fileHandleForWritingAtPath:filePath];
             }
             //did we finally get an accessable file?
             if (!hFile)
             {   //nope->bomb out!
                 NSLog(@"could not write to file %@", filePath);
                 return;
             }
             //we never know - hence we better catch possible exceptions!
             @try
             {
                 //seek to the end of the file
                 [hFile seekToEndOfFile];
                 //finally write our data to it
                 [hFile writeData:data];
             }
             @catch (NSException * e)
             {
                 NSLog(@"exception when writing to file %@", filePath);
             }
             [hFile closeFile];
         } else if ([data length] == 0 && error == nil) {
             //            [delegate emptyReply];
         } else if (error != nil && error.code == NSURLErrorTimedOut) {
             //            [delegate timedOut];
         } else if (error != nil) {
             //            [delegate downloadError:error];
         }
         [queue release];
     }];
}

这将根据需要将每个到达的大数据块附加到文件中。根据您的需要自定义请求 POST 正文,这应该可以工作。异步:)

于 2013-06-18T09:20:03.003 回答
0

好的,首先检查您的文件路径,我通常更喜欢以这种方式引用文件路径:

您需要以这种方式获取应用程序的根:

NSString* rootPath = NSHomeDirectory();

并将数据保存在Apple 文件系统指南指定的子文件夹之一中

NSString* fullPath = [rootPath stringByAppendingPathComponent:@"subFoldeder/file.extension"];

关于将新数据附加到旧数据,一个非常快速的解决方案可以通过这种方式初始化您的 videoData:

NSMutableData *videoData = [[NSMutableData alloc] initWithContentsOfFile:@"filePath"];

之后,您可以像在收到数据时已经在追加数据一样继续操作,并在最后写入完整的文件

正确的做法是不要使用太多内存,应该打开一个文件,将其搜索到最后并将数据附加到文件中

于 2013-06-18T10:11:41.487 回答