как хранить данные в NS-Mutable-данных в полученных данных, а затем записывать в файл

Я застрял с 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);

    }
 }

person Swap-IOS-Android    schedule 18.06.2013    source источник
comment
В чем проблема? Я предполагаю, что в вашем случае videoData является NSMutableData, поэтому в момент загрузки вы можете записать файл на диск iPhone, как и вы... Когда вы говорите «добавить», это означает, что у вас есть частичная загрузка, и вы хотите возобновить загрузить и добавить данные в существующий файл?   -  person Manu    schedule 18.06.2013
comment
@Manu, да, я хочу добавить старые данные к новым полученным данным, а после этого записать их в файл ... но мой файл не создан ... я просто хочу отобразить индикатор выполнения загрузки ... поэтому я использую didreceivedata by используя это, я могу отображать, сколько данных я получил, и обновлять индикатор выполнения. Я использую индикатор выполнения HUD, а не простой индикатор выполнения.   -  person Swap-IOS-Android    schedule 18.06.2013


Ответы (2)


Для такой задачи лучше использовать асинхронные запросы. Вы можете использовать тот же класс 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 для своих нужд, и это должно сработать. Асинхронно :)

person makaron    schedule 18.06.2013
comment
вы кодируете файл, но не сохраняете данные, которые я получил в ответ на запрос... - person Swap-IOS-Android; 18.06.2013
comment
Это рабочий код из одного из моих проектов. Так что, возможно, что-то не так с телом запроса или с полученными данными. Поскольку ваш код создает файл, то [длина данных] › 0 является истинным. Попробуйте вставить NSLog(@%@, data); в тело оператора if и посмотрите, что получится на выходе. Возможно, ваш сервер выдает какое-то понятное сообщение об ошибке - person makaron; 18.06.2013

Хорошо, сначала проверьте путь к файлу, я обычно предпочитаю указывать путь к файлу следующим образом:

вам нужно получить корень вашего приложения таким образом:

NSString* rootPath = NSHomeDirectory();

и сохраните данные в одной из подпапок, как указано в Руководство по файловой системе Apple

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

О добавлении новых данных к старым данным очень быстрое решение может быть инициализировано вашими видеоданными следующим образом:

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

После этого вы можете действовать так, как будто вы уже добавляете данные, когда получаете их, и записываете полный файл в конце.

Правильная вещь, чтобы не использовать слишком много памяти, должна открывать файл, искать его до конца и добавлять данные в файл.

person Manu    schedule 18.06.2013