123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- //
- // XCThemeService.m
- // XCTheme
- //
- // Created by 邢铖 on 2023/11/19.
- //
- #import "XCThemeProtocol.h"
- #import "XCTheme-Swift.h"
- #import <XCZip/XCZip.h>
- @xcmlservice(XCThemeProtocol, XCThemeService)
- @synthesize downloadBlock = _downloadBlock;
- - (UIUserInterfaceStyle)currentUserInterfaceStyle {
- return XCThemeManager.shared.currentUserInterfaceStyle;
- }
- - (void)prepareThemeTarget:(nullable NSObject *)target block:(nullable void (^)(XCThemeSpecModel * _Nullable))block {
- [XCThemeManager.shared prepareThemeBlockWithTarget:target :^(XCThemeSpec * _Nullable theme) {
- XCThemeSpecModel * _Nullable wrappedModel = [[XCThemeSpecModel alloc] initWithWrappedObject:theme];
- if (block) {
- block(wrappedModel);
- }
- }];
- }
- #pragma mark - Theme Download
- - (NSArray<XCThemeSpecModel *> *)fetchBundleSpecs {
- NSString *path = [NSBundle.mainBundle.resourcePath stringByAppendingString:@"/ThemeResources"];
- NSArray *items = [[NSFileManager.defaultManager contentsOfDirectoryAtPath:path error:nil] sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- return [obj1 compare:obj2];
- }];
- NSMutableArray<XCThemeSpecModel *> *specs = [NSMutableArray new];
- for (NSString *file in items) {
- NSString *filePath = [NSString stringWithFormat:@"%@/%@", path, file];
- BOOL isDir = NO;
- [NSFileManager.defaultManager fileExistsAtPath:filePath isDirectory:&isDir];
- if (isDir) {
- XCThemeSpec *theme = [[XCThemeSpec alloc] initWithThemeId:file];
- if (theme) {
- XCThemeSpecModel *specModel = [[XCThemeSpecModel alloc] initWithWrappedObject:theme];
- [specs addObject:specModel];
- }
- }
- }
- return [specs copy];
- }
- - (NSArray<XCThemeSpecModel *> *)fetchDownloadedSpecs {
- NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
- NSString *path = [documentsPath stringByAppendingString:@"/ThemeResources"];
- NSArray *items = [NSFileManager.defaultManager contentsOfDirectoryAtPath:path error:nil];
- NSMutableArray<XCThemeSpecModel *> *specs = [NSMutableArray new];
- for (NSString *file in items) {
- NSString *filePath = [NSString stringWithFormat:@"%@/%@", path, file];
- BOOL isDir = NO;
- [NSFileManager.defaultManager fileExistsAtPath:filePath isDirectory:&isDir];
- if (isDir) {
- XCThemeSpec *theme = [[XCThemeSpec alloc] initWithThemeId:filePath];
- if (theme) {
- XCThemeSpecModel *specModel = [[XCThemeSpecModel alloc] initWithWrappedObject:theme];
- [specs addObject:specModel];
- }
- }
- }
- return [specs copy];
- }
- - (NSArray<XCThemeSpecModel *> *)fetchLocalSpecs {
- NSMutableArray *specs = [NSMutableArray new];
- [specs addObjectsFromArray:[self fetchBundleSpecs]];
- [specs addObjectsFromArray:[self fetchDownloadedSpecs]];
- return [specs copy];
- }
- - (void)fetchThemeData:(NSString *)themeId completion:(void (^)(BOOL, NSString * _Nonnull, XCThemeSpecModel * _Nullable))completion {
- NSArray<XCThemeSpecModel *> *allLocalSpecs = [self fetchLocalSpecs];
- for (XCThemeSpecModel *spec in allLocalSpecs) {
- if ([spec.themeId isEqualToString:themeId]) {
- if (completion) {
- completion(YES, @"", spec);
- return;
- }
- }
- }
-
- if (!self.downloadBlock) {
- if (completion) {
- completion(NO, @"downloadBlock not specified", nil);
- }
- @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"downloadBlock not specified" userInfo:nil];
- }
-
- NSString *rootPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
- NSString *downloadTHMPath = [rootPath stringByAppendingFormat:@"/ThemeResources/%@.thm", themeId];
- NSString *extractPath = [rootPath stringByAppendingFormat:@"/ThemeResources/%@", themeId];
- self.downloadBlock(themeId, downloadTHMPath, ^(BOOL success, NSString * _Nonnull reason) {
- if (!success) {
- if (completion) {
- completion(NO, reason, nil);
- }
- return;
- }
- BOOL extractSuccess = [SSZipArchive unzipFileAtPath:downloadTHMPath toDestination:extractPath uniqueId:nil];
- [NSFileManager.defaultManager removeItemAtPath:downloadTHMPath error:nil];
- if (!extractSuccess) {
- [NSFileManager.defaultManager removeItemAtPath:extractPath error:nil];
- if (completion) {
- completion(NO, @"Extract download failed", nil);
- }
- return;
- }
- XCThemeSpec *spec = [[XCThemeSpec alloc] initWithThemeId:themeId];
- if (spec) {
- XCThemeSpecModel *specModel = [[XCThemeSpecModel alloc] initWithWrappedObject:spec];
- if (completion) {
- completion(YES, @"", specModel);
- }
- } else {
- [NSFileManager.defaultManager removeItemAtPath:extractPath error:nil];
- if (completion) {
- completion(NO, @"Theme not completed", nil);
- }
- }
- });
- }
- - (XCThemeSpecModel *)currentTheme {
- if (XCThemeManager.shared.selectedTheme) {
- return [[XCThemeSpecModel alloc] initWithWrappedObject:XCThemeManager.shared.selectedTheme];
- }
- return nil;
- }
- - (void)applyTheme:(XCThemeSpecModel *)localSpec {
- XCThemeManager.shared.selectedTheme = localSpec.wrappedObject;
- }
- @end
|