Files
yinmeng-ios/xplan-ios/Main/ModuleKit/FaceView/Presenter/XPRoomFaceTool.m
2022-03-10 18:57:06 +08:00

214 lines
6.8 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// XPRoomFaceTool.m
// xplan-ios
//
// Created by 冯硕 on 2022/3/9.
//
#import "XPRoomFaceTool.h"
#import <SSZipArchive.h>
#import <AFNetworking.h>
#import <CommonCrypto/CommonDigest.h>
#define FileHashDefaultChunkSizeForReadingData 1024*8 // 8K
NSString * const kRoomFaceVersion = @"kRoomFaceVersion";
@interface XPRoomFaceTool ()
///解压缩之后 表情资源所在的位置
@property (nonatomic,copy) NSString *faceDirectory;
///重试的次数
@property (nonatomic,assign) NSInteger retryCount;
@end
@implementation XPRoomFaceTool
+ (instancetype)shareFaceTool {
static dispatch_once_t onceToken;
static XPRoomFaceTool * tool;
dispatch_once(&onceToken, ^{
tool = [[XPRoomFaceTool alloc] init];
tool.retryCount = 0;
});
return tool;
}
- (void)downFaceData {
[self downFaceDataCompletion:nil];
}
- (void)downFaceDataCompletion:(nullable void (^)(NSString * nullable))completion {
//获取沙盒doucument路径
NSArray*pathsss =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDirectory = [pathsss objectAtIndex:0];
NSString*faceDirectory = [documentsDirectory stringByAppendingPathComponent:@"Face"];
///首先判断 本地的数据是否 需要更新了
NSString *version = [[NSUserDefaults standardUserDefaults]objectForKey: kRoomFaceVersion];
if (version == nil || version.integerValue < self.version.integerValue) {///本地没有保存的话 就走下载
if (self.zipUrl.length > 0 && [self.zipUrl hasPrefix:@"http"]) {
NSURL *URL = [NSURL URLWithString:self.zipUrl];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
//请求
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
//下载Task操作
[[manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//要求返回一个URL, 返回的这个URL就是文件的位置的路径
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if (error == nil) {
NSString *filePathStr = [filePath path];
NSString *fileMD5Str = [self getFileMD5WithPath:filePathStr];
fileMD5Str = [fileMD5Str uppercaseString];
if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5校验 如果不相等就重新下载
[self performSelector:@selector(downFaceData) withObject:nil afterDelay:3];
}else {
// filePath就是你下载文件的位置你可以解压也可以直接拿来使用
NSString *imgFilePath = [filePath path];
NSLog(@"img == %@", imgFilePath);
NSString *zipPath = imgFilePath;
NSFileManager *fileManager = [NSFileManager defaultManager];
//删除老的数据
[[NSFileManager defaultManager] removeItemAtPath:faceDirectory error:nil];
[fileManager createDirectoryAtPath:faceDirectory withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(@"test == %@",faceDirectory); //解压后的路径
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//解压
[SSZipArchive unzipFileAtPath:zipPath toDestination:faceDirectory overwrite:YES password:nil progressHandler:^(NSString * _Nonnull entry, unz_file_info zipInfo, long entryNumber, long total) {
} completionHandler:^(NSString * _Nonnull path, BOOL succeeded, NSError * _Nullable error) {
if (error == nil) {
self.retryCount = 0;
///如果解压完成的话 就保存一下值
[[NSUserDefaults standardUserDefaults]setObject:self.version forKey:kRoomFaceVersion];
self.faceDirectory = faceDirectory;
if (completion) {
completion(faceDirectory);
}
} else {
self.retryCount ++;
if (self.retryCount <=10) {
[self downFaceData];
}
if (completion) {
completion(nil);
}
}
}];
});
}
} else {
self.retryCount ++;
if (self.retryCount <=10) {
[self downFaceData];
}
if (completion) {
completion(nil);
}
}
}] resume];
} else {
if (completion) {
completion(nil);
}
}
} else {
self.faceDirectory = faceDirectory;
if (completion) {
completion(faceDirectory);
}
}
}
- (NSString*)getFileMD5WithPath:(NSString*)path {
return (__bridge NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path,FileHashDefaultChunkSizeForReadingData);
}
CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,
size_t chunkSizeForReadingData) {
// Declare needed variables
CFStringRef result = NULL;
CFReadStreamRef readStream = NULL;
// Get the file URL
CFURLRef fileURL =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(CFStringRef)filePath,
kCFURLPOSIXPathStyle,
(Boolean)false);
CC_MD5_CTX hashObject;
bool hasMoreData = true;
bool didSucceed;
if (!fileURL) goto done;
// Create and open the read stream
readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
(CFURLRef)fileURL);
if (!readStream) goto done;
didSucceed = (bool)CFReadStreamOpen(readStream);
if (!didSucceed) goto done;
// Initialize the hash object
CC_MD5_Init(&hashObject);
// Make sure chunkSizeForReadingData is valid
if (!chunkSizeForReadingData) {
chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
}
// Feed the data to the hash object
while (hasMoreData) {
uint8_t buffer[chunkSizeForReadingData];
CFIndex readBytesCount = CFReadStreamRead(readStream,
(UInt8 *)buffer,
(CFIndex)sizeof(buffer));
if (readBytesCount == -1)break;
if (readBytesCount == 0) {
hasMoreData =false;
continue;
}
CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
}
// Check if the read operation succeeded
didSucceed = !hasMoreData;
// Compute the hash digest
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &hashObject);
// Abort if the read operation failed
if (!didSucceed) goto done;
// Compute the string result
char hash[2 *sizeof(digest) + 1];
for (size_t i =0; i < sizeof(digest); ++i) {
snprintf(hash + (2 * i),3, "%02x", (int)(digest[i]));
}
result = CFStringCreateWithCString(kCFAllocatorDefault,
(const char *)hash,
kCFStringEncodingUTF8);
done:
if (readStream) {
CFReadStreamClose(readStream);
CFRelease(readStream);
}
if (fileURL) {
CFRelease(fileURL);
}
return result;
}
@end