首次提交

This commit is contained in:
启星
2025-08-08 11:05:33 +08:00
parent 1b3bb91b4a
commit adc1a2a25d
8803 changed files with 708874 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
//
// AOESVGAEntity.h
// AOESVGASimple
//
// Created by 夏宁忠 on 2018/3/9.
// Copyright © 2018年 夏宁忠. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface AOESVGAEntity : NSObject
/**
svga文件版本:如果存在本地存储可能出现URL相同但服务端文件已经更新
*/
@property (nonatomic, strong)NSString *svga_version;
/**
SVGA URL 网络/本地
*/
@property (nonatomic, strong)NSString *svga_url;
/**
SVGA 标题
*/
@property (nonatomic, strong)NSString *svga_title;
/**
SVGA 描述
*/
@property (nonatomic, strong)NSString *svga_description;
/**
SVGA 基于父视图的位置
*/
@property (nonatomic, assign)CGRect svga_forSupviewRect;
/**
SVGA 显示的父视图
*/
@property (nonatomic, strong)id superView;
@end

View File

@@ -0,0 +1,13 @@
//
// AOESVGAEntity.m
// AOESVGASimple
//
// Created by on 2018/3/9.
// Copyright © 2018 . All rights reserved.
//
#import "AOESVGAEntity.h"
@implementation AOESVGAEntity
@end

View File

@@ -0,0 +1,26 @@
//
// AOESVGAQueue.h
// AOESVGASimple
//
// Created by 夏宁忠 on 2018/3/9.
// Copyright © 2018年 夏宁忠. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AOESVGAEntity.h"
@interface AOESVGAQueue : NSObject
/**
是否开启本地存储
*/
@property (nonatomic, assign)BOOL isMemory;
/**
添加动画进队列
@param entity 动画信息对象
*/
-(void)addSVGAInQueue:(AOESVGAEntity *)entity;
@end

View File

@@ -0,0 +1,134 @@
//
// AOESVGAQueue.m
// AOESVGASimple
//
// Created by on 2018/3/9.
// Copyright © 2018 . All rights reserved.
//
#import "AOESVGAQueue.h"
#if __has_include(<SVGAPlayer/SVGA.h>)
#import <SVGAPlayer/SVGA.h>
#elif __has_include("SVGAPlayer/SVGA.h")
#import "SVGAPlayer/SVGA.h"
#else
#import "SVGA.h"
#endif
#import "SVGAParser+AOESVGAMemory.h"
@interface AOESVGAQueue ()<SVGAPlayerDelegate>
@property (nonatomic, strong)NSOperationQueue *queue;
@property (nonatomic, strong) SVGAPlayer *aPlayer;
@property (nonatomic, strong) SVGAParser *parser;
@end
@implementation AOESVGAQueue
-(void)addSVGAInQueue:(AOESVGAEntity *)entity{
__weak typeof(self)weakSelf = self;
[self.queue addOperationWithBlock:^{
//,SVGAParser
[weakSelf.queue setSuspended:YES];
//UI 线
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf playSVGA:entity];
});
}];
}
-(void)playSVGA:(AOESVGAEntity *)entity{
self.aPlayer.frame = entity.svga_forSupviewRect;
[entity.superView addSubview:self.aPlayer];
__weak typeof(self)weakSelf = self;
if (self.isMemory == YES) {
[self.parser parseMemoryWithURL:[NSURL URLWithString:entity.svga_url] Version:entity.svga_version completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (videoItem != nil) {
weakSelf.aPlayer.videoItem = videoItem;
[weakSelf.aPlayer startAnimation];
}
} failureBlock:nil];
}else{
[self.parser parseWithURL:[NSURL URLWithString:entity.svga_url] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (videoItem != nil) {
weakSelf.aPlayer.videoItem = videoItem;
[weakSelf.aPlayer startAnimation];
}
} failureBlock:nil];
}
}
#pragma mark - <SVGAPlayerDelegate>
-(void)svgaPlayerDidFinishedAnimation:(SVGAPlayer *)player{
//
[self.queue setSuspended:NO];
if (self.queue.operations.count==0) {
//SVGAPlayer
[self.aPlayer removeFromSuperview];
}
}
#pragma mark - dealloc
-(void)dealloc{
NSLog(@"AOESVGAQueue dealloc");
}
#pragma mark - setter/getter
-(SVGAPlayer *)aPlayer{
if (!_aPlayer) {
_aPlayer = [[SVGAPlayer alloc]init];
_aPlayer.delegate = self;
_aPlayer.loops = 1;
_aPlayer.clearsAfterStop = YES;
}
return _aPlayer;
}
-(SVGAParser *)parser{
if (!_parser) {
_parser = [[SVGAParser alloc]init];
}
return _parser;
}
-(NSOperationQueue *)queue{
if (!_queue) {
_queue = [[NSOperationQueue alloc]init];
_queue.maxConcurrentOperationCount = 1;
}
return _queue;
}
@end

View File

@@ -0,0 +1,45 @@
//
// SVGAParser+AOESVGAMemory.h
// AOESVGASimple
//
// Created by 夏宁忠 on 2018/3/9.
// Copyright © 2018年 夏宁忠. All rights reserved.
//
#if __has_include(<SVGAPlayer/SVGAParser.h>)
#import <SVGAPlayer/SVGAParser.h>
#elif __has_include("SVGAPlayer/SVGAParser.h")
#import "SVGAPlayer/SVGAParser.h"
#else
#import "SVGAParser.h"
#endif
#define AOESVGAMemoryDir @"SVGA" //设置Document 下SVGA文件存储路径
@interface SVGAParser (AOESVGAMemory)
/**
通过url加载svga动画,设置svga文件存储
@param URL url
@param completionBlock 成功回调
@param failureBlock 失败回调
*/
- (void)parseMemoryWithURL:(nonnull NSURL *)URL
Version:(NSString *_Nullable)version
completionBlock:(void ( ^ _Nonnull )(SVGAVideoEntity * _Nullable videoItem))completionBlock
failureBlock:(void ( ^ _Nullable)(NSError * _Nullable error))failureBlock;
/**
本地存储大小
@param sucBlock size k
*/
+ (void)memoryAllSzie:(void (^ _Nullable)(NSUInteger size))sucBlock;
/**
移除所有本地的SVGA相关文件
*/
+ (void)removeAllMemorySvgas:(void ( ^ _Nullable)(BOOL suc))sucBlock;
@end

View File

@@ -0,0 +1,322 @@
//
// SVGAParser+AOESVGAMemory.m
// AOESVGASimple
//
// Created by on 2018/3/9.
// Copyright © 2018 . All rights reserved.
//
#import "SVGAParser+AOESVGAMemory.h"
#import <CommonCrypto/CommonDigest.h>
@implementation SVGAParser (AOESVGAMemory)
-(void)parseMemoryWithURL:(NSURL *)URL Version:(NSString * _Nullable)version completionBlock:(void (^ _Nonnull)(SVGAVideoEntity * _Nullable))completionBlock failureBlock:(void (^ _Nullable)(NSError * _Nullable))failureBlock{
NSFileManager * fileMgr = [NSFileManager defaultManager];
NSString *dir = [self memorySVGADir:URL];
NSString * svgaFilePath = [dir stringByAppendingString:[NSString stringWithFormat:@"/%@.svga",[self MD5StringExt:URL.absoluteString]]];
NSString * versionFilePath = [dir stringByAppendingString:@"/version.text"];
if ([fileMgr fileExistsAtPath:svgaFilePath]) { //
//version version
if ([fileMgr fileExistsAtPath:versionFilePath]) {
NSString * versionStr = [NSString stringWithContentsOfFile:versionFilePath encoding:NSUTF8StringEncoding error:nil];
if ([versionStr isEqualToString:version]) {
//
NSURL * locationUrl = [NSURL fileURLWithPath:svgaFilePath];
[self parseWithURL:locationUrl completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionBlock(videoItem);
}];
}
} failureBlock:^(NSError * _Nullable error) {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}];
}else{ //
//
//version svgaversion
[[[NSURLSession sharedSession] dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil && data != nil) {
[self parseWithURL:URL completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionBlock(videoItem);
}];
}
} failureBlock:^(NSError * _Nullable error) {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//svga
BOOL svgaWrite = [data writeToFile:svgaFilePath atomically:YES];
if (svgaWrite == NO) {
[fileMgr removeItemAtPath:svgaFilePath error:nil];
}
//
NSString * svga_version = (version && ![version isEqualToString:@""]) ? version : @"0";
BOOL versionWrite = [svga_version writeToFile:versionFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (versionWrite == NO) {
[fileMgr removeItemAtPath:versionFilePath error:nil];
}
});
}else {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}
}] resume];
}
}else{
//version svgaversion
[[[NSURLSession sharedSession] dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil && data != nil) {
[self parseWithURL:URL completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionBlock(videoItem);
}];
}
} failureBlock:^(NSError * _Nullable error) {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//svga
BOOL svgaWrite = [data writeToFile:svgaFilePath atomically:YES];
if (svgaWrite == NO) {
[fileMgr removeItemAtPath:svgaFilePath error:nil];
}
//
NSString * svga_version = (version && ![version isEqualToString:@""]) ? version : @"0";
//Version,
if (![fileMgr fileExistsAtPath:versionFilePath]) {
[fileMgr createFileAtPath:versionFilePath contents:nil attributes:nil];
}
BOOL versionWrite = [svga_version writeToFile:versionFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (versionWrite == NO) {
[fileMgr removeItemAtPath:versionFilePath error:nil];
}
});
}else {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}
}] resume];
}
return;
}
//svga svga
//svga
[[[NSURLSession sharedSession] dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil && data != nil) {
[self parseWithURL:URL completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionBlock(videoItem);
}];
}
} failureBlock:^(NSError * _Nullable error) {
if (failureBlock) {
failureBlock(error);
}
}];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//svga
[fileMgr createFileAtPath:svgaFilePath contents:data attributes:nil];
//
NSString * svga_version = (version && ![version isEqualToString:@""]) ? version : @"0";
//Version,
if (![fileMgr fileExistsAtPath:versionFilePath]) {
[fileMgr createFileAtPath:versionFilePath contents:nil attributes:nil];
}
BOOL versionWrite = [svga_version writeToFile:versionFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (versionWrite == NO) {
[fileMgr removeItemAtPath:versionFilePath error:nil];
}
});
}else {
if (failureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
failureBlock(error);
}];
}
}
}] resume];
}
+(void)memoryAllSzie:(void (^)(NSUInteger))sucBlock{
//
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *memoryDirPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingString:[NSString stringWithFormat:@"/%@",AOESVGAMemoryDir]];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dir = NO;
[fileManager fileExistsAtPath:memoryDirPath isDirectory:&dir];
NSUInteger totalByteSize = 0;
if (dir) { //SVGA
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:memoryDirPath];
for (NSString *subpath in enumerator) {
//
NSString *fullSubpath = [memoryDirPath stringByAppendingPathComponent:subpath];
//
totalByteSize += [fileManager attributesOfItemAtPath:fullSubpath error:nil].fileSize;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (sucBlock) {
sucBlock(totalByteSize);
}
});
});
}
+(void)removeAllMemorySvgas:(void (^)(BOOL))sucBlock{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *memoryDirPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingString:[NSString stringWithFormat:@"/%@",AOESVGAMemoryDir]];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dir = NO;
[fileManager fileExistsAtPath:memoryDirPath isDirectory:&dir];
BOOL isSuccess = NO;
if (dir) { //
isSuccess = [fileManager removeItemAtPath:memoryDirPath error:nil];
}else{
isSuccess = YES;
}
dispatch_async(dispatch_get_main_queue(), ^{
if (sucBlock) {
sucBlock(isSuccess);
}
});
});
}
#pragma mark - Private
//SVGA
-(nullable NSString *)memorySVGADir:(NSURL *)url{
NSFileManager * fileMgr = [NSFileManager defaultManager];
NSString *memoryDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingString:[NSString stringWithFormat:@"/%@/%@",AOESVGAMemoryDir,[self MD5StringExt:url.absoluteString]]];
BOOL dir = NO;
[fileMgr fileExistsAtPath:memoryDir isDirectory:&dir];
if (dir == NO) { //
[fileMgr createDirectoryAtPath:memoryDir withIntermediateDirectories:YES attributes:nil error:nil];
}
return memoryDir;
}
- (NSString *)MD5StringExt:(NSString *)str {
const char *cstr = [str UTF8String];
unsigned char result[16];
CC_MD5(cstr, (CC_LONG)strlen(cstr), result);
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
@end