Browse Source

【功能】接口增加版本哈希,可以控制永远使用最新版本

xcbosa mbp16 1 year ago
parent
commit
0c7ffb99e3

+ 0 - 0
XCTheme/Classes/Impl/XCThemeManager.swift → XCTheme/Classes/Business/XCThemeManager.swift


+ 19 - 4
XCTheme/Classes/Impl/XCThemeService.m → XCTheme/Classes/Business/XCThemeService.m

@@ -104,9 +104,8 @@
     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) {
+- (void)fetchThemeData:(NSString *)themeId versionHash:(nullable NSString *)versionHash completion:(void (^)(BOOL, NSString * _Nonnull, XCThemeSpecModel * _Nullable))completion {
+    for (XCThemeSpecModel *spec in [self fetchBundleSpecs]) {
         if ([spec.themeId isEqualToString:themeId]) {
             if (completion) {
                 completion(YES, @"", spec);
@@ -115,6 +114,21 @@
         }
     }
     
+    for (XCThemeSpecModel *spec in [self fetchDownloadedSpecs]) {
+        if ([spec.themeId isEqualToString:themeId]) {
+            if (versionHash) {
+                if (![versionHash isEqualToString:spec.storagedVersionHash ?: @""]) {
+                    [NSFileManager.defaultManager removeItemAtPath:spec.containerPath error:nil];
+                    break;
+                }
+            }
+            if (completion) {
+                completion(YES, @"", spec);
+                return;
+            }
+        }
+    }
+    
     if (!self.downloadBlock) {
         if (completion) {
             completion(NO, @"downloadBlock not specified", nil);
@@ -135,7 +149,7 @@
     }
     NSString *downloadTHMPath = [rootPath stringByAppendingFormat:@"/ThemeResources/%@.thm", themeId];
     NSString *extractPath = [rootPath stringByAppendingFormat:@"/ThemeResources/%@", themeId];
-    self.downloadBlock(themeId, downloadTHMPath, ^(BOOL success, NSString * _Nonnull reason) {
+    self.downloadBlock(themeId, downloadTHMPath, ^(BOOL success, NSString * _Nonnull reason, NSString *_Nullable versionHash) {
         if (!success) {
             if (completion) {
                 completion(NO, reason, nil);
@@ -154,6 +168,7 @@
         XCThemeSpec *spec = [[XCThemeSpec alloc] initWithThemeId:themeId];
         if (spec) {
             XCThemeSpecModel *specModel = [[XCThemeSpecModel alloc] initWithWrappedObject:spec];
+            specModel.storagedVersionHash = versionHash;
             if (completion) {
                 completion(YES, @"", specModel);
             }

+ 0 - 0
XCTheme/Classes/Impl/XCThemeSpec.swift → XCTheme/Classes/Business/XCThemeSpec.swift


+ 2 - 0
XCTheme/Classes/Module/XCThemeSpecModel.h → XCTheme/Classes/Business/XCThemeSpecModel.h

@@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, strong, readonly) id wrappedObject;
 
+@property (nonatomic, copy, nullable) NSString *storagedVersionHash;
+
 @property (nonatomic, copy, readonly) NSString *themeId;
 @property (nonatomic, copy, readonly, nullable) NSString *containerPath;
 @property (nonatomic, copy, readonly, nullable) NSDictionary<NSString *, NSObject *> *originalDict;

+ 23 - 0
XCTheme/Classes/Module/XCThemeSpecModel.m → XCTheme/Classes/Business/XCThemeSpecModel.m

@@ -89,4 +89,27 @@
     return self.wrappedObject.useSystemAppearance;
 }
 
+- (nullable NSString *)storagedVersionHash {
+    NSString *versionMetaFilePath = [self.containerPath stringByAppendingString:@"/version.meta"];
+    if ([NSFileManager.defaultManager fileExistsAtPath:versionMetaFilePath]) {
+        NSError *error;
+        NSString *versionHash = [NSString stringWithContentsOfFile:versionMetaFilePath encoding:NSUTF8StringEncoding error:&error];
+        if (error) {
+            return nil;
+        }
+        return versionHash;
+    }
+    return nil;
+}
+
+- (void)setStoragedVersionHash:(nullable NSString *)storagedVersionHash {
+    NSString *versionMetaFilePath = [self.containerPath stringByAppendingString:@"/version.meta"];
+    if ([NSFileManager.defaultManager fileExistsAtPath:versionMetaFilePath]) {
+        [NSFileManager.defaultManager removeItemAtPath:versionMetaFilePath error:nil];
+    }
+    if (storagedVersionHash) {
+        [storagedVersionHash writeToFile:versionMetaFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
+    }
+}
+
 @end

+ 3 - 2
XCTheme/Classes/Module/XCThemeProtocol.h

@@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
 #pragma mark - For Theme Data Sync
 /// Download the give themeId
 /// @discussion themeId may not the key for storage system, the interface layer should fetch the themeId-downloadURL pairs from server first, then call fetchThemeData method to start download contents. Must be settled before call fetchThemeData:completion:
-@property (nonatomic, copy, nullable) void (^downloadBlock)(NSString *themeId, NSString *writeToPath, void (^)(BOOL success, NSString *reason));
+@property (nonatomic, copy, nullable) void (^downloadBlock)(NSString *themeId, NSString *writeToPath, void (^)(BOOL success, NSString *reason, NSString * _Nullable versionHash));
 
 /// block will called when theme engine loaded, should return a default theme identifier
 /// @discussion should be set on `moduleLoadedWithArgs:`, the block will called after main framework prepared
@@ -45,10 +45,11 @@ NS_ASSUME_NONNULL_BEGIN
 
 /// Fetch spec data with specified themeId
 /// @param themeId The id of theme, possible pure number indicate downloaded resources, english words indicate bundle resources
+/// @param versionHash The required hash. If given and not equal than the local download theme, will discard local data and call downloadBlock again
 /// @param completion finish block
 /// @discussion If theme data exists in local, will call completion sync
 /// @discussion If theme data not exists in local, will download first and call completion async
-- (void)fetchThemeData:(NSString *)themeId completion:(nullable void (^)(BOOL success, NSString *errorReason, XCThemeSpecModel *spec))completion;
+- (void)fetchThemeData:(NSString *)themeId versionHash:(nullable NSString *)versionHash completion:(nullable void (^)(BOOL success, NSString *errorReason, XCThemeSpecModel *spec))completion;
 
 /// Must exists, return the current selected theme
 /// @discussion Theme always contains systemDark, systemLight or systemAdaptive, so the return value must not null