一,正確保存文件的位置
?? iOS 開發(fā)中,音頻或者視頻是非常耗費內(nèi)存的東西,所以如果文件存放的地方不對的話將會不斷的占用系統(tǒng)的內(nèi)存容量,畢竟手機的內(nèi)存是有限的,所以我們開發(fā)人員必須合理的管理內(nèi)存資源。所以為了合理的管理音頻和視頻的文件資源,我們一般將這些占用內(nèi)存比較大的資源存放到緩存中,如果清空緩存的時候,就會自動清理這些資源,從而釋放內(nèi)存。所以我們導(dǎo)入AFNetWorking 第三方庫。
二,進行相關(guān)的下載工作
(1)首先獲取沙河路徑,從而更好的獲取緩存路徑
NSArray *firstPathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);//獲取沙河路徑
NSString *firthPath = [firstPathArray firstObject];//獲取緩存
(2)其次,在緩存路徑中創(chuàng)建一個專門存放mp3文件的文件夾,
NSString *allFilePath = [firthPath stringByAppendingPathComponent:@"MP3File"];//創(chuàng)建一個MP3File文件夾,
BOOL isDir = NO;
BOOL isExisted = [fileManager fileExistsAtPath:mp3FielPath isDirectory:&isExisted];//堅持文件夾是否存在
if (!(isDir == YES && isExisted == YES)) {//確保文件夾一定會被創(chuàng)建成果,以便于音頻文件的存儲
[fileManager createDirectoryAtPath:mp3FielPath withIntermediateDirectories:YES attributes:nil error:nil];
}
?????????????? 注:如果沒有這個if語句判斷,文件夾很可能沒有被執(zhí)行創(chuàng)建,音頻文件也沒法存儲,從而也就不能播放
(3)獲取下載單詞mp3文件的路徑,(這里是根據(jù)詞道單詞ID 進行生成下載路徑)
YOWordModel *wordModel = [[DataBaseManager shareDataBaseManager]getWordAndWordIDAccrodingToBookWordID:bookWordID];//從數(shù)據(jù)庫中選取單詞的意思和ID
NSString *nameFile = [[VoiceRoldClass shareVoiceLoad]makeBackLockedWayToSaveLoadAccrodingToWordID:wordModel.wordID];//選出單詞發(fā)音的字段通過md5加密生成最終存放在文件夾里的文件名
NSString *downloadPath = [[VoiceRoldClass shareVoiceLoad]makeWordDownloadWayAccrodingToWordID:wordModel.wordID andWord:wordModel.word];//得到最終的下載路徑
三,文件操作
?? 文件操作顧名思義就是優(yōu)先從文件中讀取相應(yīng)的文件內(nèi)容,如果文件夾中有當前需要播放的語音文件,就直接從文件夾從取數(shù)據(jù)進行相應(yīng)的操作,不用來回的請求服務(wù)器,節(jié)省資源,也減少了對服務(wù)器的響應(yīng),所以在此本人在數(shù)據(jù)庫中插入了一張表來專門記錄此單詞是否已經(jīng)被下載過,通過查詢數(shù)據(jù)庫就可以知道是否需要請求服務(wù)器。
BOOL isDownloaded = [[DataBaseManager shareDataBaseManager]getWordMP3isDownloadedfromWordDownloadTableAccrodingToBookWordID:wordModel.wordID];
如果該單詞的文件被下載了,所以我們根據(jù)上邊所生成的文件名之間去文件中讀取MP3文件,直接采用AVAudioPlayer讀取mp3文件,
if (isDownloaded == YES) {
[fileManager createDirectoryAtPath:allFilePath withIntermediateDirectories:YES attributes:nil error:nil];;//拷貝創(chuàng)建的文件夾
NSString *lastPath = [allFilePath stringByAppendingPathComponent:destinationFile];
BOOL isExistTheMp3File = [fileManager fileExistsAtPath:lastPath];//判斷文件是否存在
if (isExistTheMp3File) {
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:lastPath] error:nil];
_player.delegate = self;
[_player play];//播放語音
}
? 如果mp3文件沒有存在本地,那就要直接去訪問服務(wù)器,并且直接播放。甚至要進行寫入文件夾操作,
四,去服務(wù)器下載文件
??? 用AFNetWorking 下載文件,先要創(chuàng)建一個任務(wù)配置文件,這是下載文件必須必備的
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];
? 注,在下載服務(wù)器中應(yīng)該注意幾種特殊的情況,在下載路徑有特殊字符的時候要進行轉(zhuǎn)義,否則改文件無法下載成功。例如:空格,@? , %等等,具體的轉(zhuǎn)義字符自己了解。
?? 轉(zhuǎn)義操作如下,
if ([downloadPath containsString:@" "]) {
NSArray *newArray = [string componentsSeparatedByString:@" "];
NSString *newString = [newArray componentsJoinedByString:@"%20"];
lastString = newString;//空格的轉(zhuǎn)義用@“20%”代替,其他的同理
}
執(zhí)行下載文件的方法
NSURLRequest *requestSound = [NSURLRequest requestWithURL:[NSURL URLWithString:lastString]];//生成request文件
NSURLSessionDownloadTask *downloadTask = [sessionManager downloadTaskWithRequest:requestSound progress:nil destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {//此代碼塊中需要返回的是最終生成音頻存儲文件的二進制文件,所以和上邊生成存儲的是一樣的文件,不同的是此代碼塊自動轉(zhuǎn)二進制,不需要人為操縱。
NSURL *downloadURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
這里通過相應(yīng)文件的.進行分割,旨在獲取通過獲取前半部分字符串來加密,從而確保文件夾中存放的音頻文件和準備下載所生成的代碼完全一致,從而更好的讀取本地文件
NSString *tempString = [[[response suggestedFilename]componentsSeparatedByString:@"."]firstObject];
NSString *secString =[[[response suggestedFilename]componentsSeparatedByString:@"."]lastObject];
NSString *lastName = [[MyMD5 md5:tempString]stringByAppendingString:[NSString stringWithFormat:@".%@",secString]];
return [downloadURL URLByAppendingPathComponent:[NSString stringWithFormat:@"MP3File/%@",lastName]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
//下載完畢 將文件寫入文件夾
NSData *data = [NSData dataWithContentsOfURL:filePath];
[data writeToURL:filePath atomically:YES];
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:filePath error:nil];//直接播放
_player.delegate = self;
[_player play];
}];
[downloadTask resume];//完全下載文件流程,