我正在從我自己的web服務下載一個文件(.json),當它完成下載時,我需要將內容'解包'到本地SQLlite數據庫中。如何判斷文件何時完成下載並準備使用?
我強調NSURLConnection在另一個線程上異步下載文件以保持主線程打開。問題是,當文件下載已經開始時,主線程顯然會繼續做它正在做的事情 - 在這種情況下,試圖將文件的內容加載到數據庫中。在發生這種情況時,文件或者不存在或者存在但尚未完成。
如何運行將文件內容輸入到數據庫中的方法僅在文件實際完全下載並準備使用後?
-(void)downloadTheFileFrom:(NSString*)url withToken:(NSString*)token
{
NSString *conURL = [NSString stringWithFormat:@"%@/%@", apiURL, url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:conURL]];
[request setHTTPMethod:@"GET"];
[request addValue:@"application/json" forHTTPHeaderField:(@"content-type")];
[request addValue:token forHTTPHeaderField:(@"X-TOKEN")];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[conn start];
[self saveJsonToDatabase];
}
方法是將文件保存到數據庫:
-(void)saveJsonToDatabase
{
NSString *jsonFileToSave = @"drug.json";
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSError *jsonError = nil;
NSString *jsonFile = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/content/formulary/files/%@", jsonFileToSave]];
NSData *jsonData = [NSData dataWithContentsOfFile:jsonFile];
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&jsonError];
NSString *formularyTable = [NSString stringWithFormat:@"formulary_%@", [jsonFileToSave stringByDeletingPathExtension]];
FormularyDBManager *formularyDBManagerInstance = [FormularyDBManager new];
[formularyDBManagerInstance insertInto:formularyTable arrayOfDicts:jsonArray];
}
爲NSURLConnection的委託方法:
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *apiUrl = [NSString stringWithFormat:@"%@",[response URL]];
NSArray *pathComponents = [apiUrl pathComponents];
NSString *areaFolder = [pathComponents objectAtIndex:3];
NSString *fileName = [response suggestedFilename];
NSString *fileType = [fileName pathExtension];
NSString *docsfolderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *folderPath = [docsfolderPath stringByAppendingString:[NSString stringWithFormat:@"/content/%@/%@", areaFolder, contentType]];
BOOL isDir;
NSFileManager *fileManager= [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:folderPath isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(@"FileDownloader - connection - Error: Create folder failed %@", folderPath);
NSString *filePath = [folderPath stringByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
connection.file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
_currentFile = fileName;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[connection.file writeData:data];
}
-(NSCachedURLResponse *)connection:(FileURLConnection *)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection.file closeFile];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"GetData - connection - error - %@", error);
}
這看起來可能適合什麼我要找的。我可以定義文件的保存位置嗎?我使用這個類來保存大量文件,這只是一個我必須'interecpt'並將他們的內容放入數據庫的情況。 – Ryan
您可以將文件移到傳遞的位置。 '[[NSFileManager defaultManager] copyItemAtPath:tempLocation toPath:passedFilePath error:nil];'應該這樣做。 – Amset
重寫我的代碼並添加建議的更改後,現在按預期工作。此外,這種方法似乎比委託方法的負載也要擔心得多。謝謝! – Ryan