当前位置: 首页 > news >正文

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置更切换主题,主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。

比如新年主题风格,常见的背景显示红色氛围图片、tabbar显示新年风格的按钮样式、导航条显示红色样式等。
在这里插入图片描述

一、主题Json对应的model

这里使用JsonModel将主题转成model

model代码如下

SDAppThemeConfigViewModel.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>/**Navigation主题样式*/
@interface SDAppThemeConfigNavViewModel : NSObject@property (nonatomic, strong) NSString *backgroundColor;
@property (nonatomic, strong) NSString *backgroundImage;@property (nonatomic, strong) UIImage *t_backgroundImage;@property (nonatomic, strong) NSString *btnImageColor;
@property (nonatomic, strong) NSString *btnTitleColor;
@property (nonatomic, strong) NSString *navTitleColor;@property (nonatomic, strong) NSString *showLine;
@property (nonatomic, strong) NSString *lineColor;@end/**单个tab按钮样式*/
@interface SDAppThemeConfigTabItemViewModel : NSObject@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *titleColor;
@property (nonatomic, strong) NSString *selectedTitleColor;
@property (nonatomic, strong) NSString *icon;
@property (nonatomic, strong) NSString *selectedIcon;@property (nonatomic, strong) UIImage *t_icon;
@property (nonatomic, strong) UIImage *t_selectedIcon;@end/**tabbar样式*/
@interface SDAppThemeConfigTabViewModel : NSObject@property (nonatomic, strong) NSString *backgroundColor;
@property (nonatomic, strong) NSString *backgroundImage;
@property (nonatomic, strong) NSString *showLine;
@property (nonatomic, strong) NSString *lineColor;
@property (nonatomic, strong) NSString *badgeBgColor;@property (nonatomic, strong) UIImage *t_backgroundImage;@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *lianlian;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *guangguang;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *message;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *shop;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *mine;@end/**将本地的主题config.json转成viewmodel*/
@interface SDAppThemeConfigViewModel : NSObject@property (nonatomic, strong) NSString *globalColor;
@property (nonatomic, strong) NSString *globalImage;
@property (nonatomic, strong) SDAppThemeConfigNavViewModel *navigation;
@property (nonatomic, strong) SDAppThemeConfigTabViewModel *tabbar;@property (nonatomic, strong) UIImage *t_globalImage;+ (SDAppThemeConfigViewModel *)themeViewModel:(NSString *)themeJson;+ (SDAppThemeConfigViewModel *)defautThemeViewModel;@end

SDAppThemeConfigViewModel.m

#import "SDAppThemeConfigViewModel.h"
#import <NSObject+YYModel.h>/**Navigation主题样式*/
@implementation SDAppThemeConfigNavViewModel@end/**单个tab按钮样式*/
@implementation SDAppThemeConfigTabItemViewModel@end/**tabbar样式*/
@implementation SDAppThemeConfigTabViewModel@end/**将本地的主题config.json转成viewmodel*/
@implementation SDAppThemeConfigViewModel+ (SDAppThemeConfigViewModel *)themeViewModel:(NSString *)themeJson {return [SDAppThemeConfigViewModel modelWithJSON:themeJson];
}+ (SDAppThemeConfigViewModel *)defautThemeViewModel {SDAppThemeConfigViewModel *viewModel = [[SDAppThemeConfigViewModel alloc] init];SDAppThemeConfigNavViewModel *navConfigViewModel = [[SDAppThemeConfigNavViewModel alloc] init];navConfigViewModel.backgroundColor = @"171013";navConfigViewModel.btnImageColor = @"ffffff";navConfigViewModel.btnTitleColor = @"ffffff";navConfigViewModel.navTitleColor = @"ffffff";viewModel.navigation = navConfigViewModel;return viewModel;
}@end

二、实现下载解压主题

2.1 AFNetworking下载

下载使用的是AFNetworking下载功能。AFNetworking是一个轻量级的iOS网络通信类库。

下载代码:

#pragma mark - Http download
/**请求下载@param aUrl aurl@param aSavePath aSavePath@param aFileName aFileName@param aTag aTag@param downloadprogress downloadprogress@param success success@param failure failure*/
- (void)downloadFileURL:(NSString *)aUrlsavePath:(NSString *)aSavePathfileName:(NSString *)aFileNametag:(NSInteger)aTagdownloadProgress:(void(^)(CGFloat progress))downloadprogresssuccess:(void(^)(NSURLResponse *response,NSString *filePath))successfailure:(void(^)(HttpError * e))failure {NSFileManager *fileManger = [NSFileManager defaultManager];if ([fileManger fileExistsAtPath:[aSavePath stringByAppendingPathComponent:aFileName]]) {//文件存在return;}//2.确定请求的URL地址NSString *requestUrl = [self requestUrlWithPath:aUrl clientType:HttpClientTypeWithOut];NSMutableURLRequest *request = [self.httpManager.requestSerializer requestWithMethod:@"GET" URLString:requestUrl parameters:nil error:nil];__block NSURLSessionDownloadTask *downloadTask = nil;downloadTask = [self.httpManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {dispatch_async(dispatch_get_main_queue(), ^{downloadprogress(1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);});} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {return [NSURL fileURLWithPath:aSavePath];} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {if(error == nil) {success(response,[filePath path]);} else {//下载失败NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;HttpError *e = [self httpRequestFailure:httpResponse error:error];failure(e);}}];[downloadTask resume];
}

2.2 判断主题版本是否已经下载

在获取主题版本时候,需要判断主题是否存在,如果存在,则直接获取保存的地址。不存在,下载解压当前版本的主题包。

//判断当前主题版本号下是否存在资源文件夹BOOL curThemeExist = [self hasAppThemeVersion:themeModel.curVersion];if (!curThemeExist) {//如果不存在,重新下载解压__block NSString *saveZipPath = [self saveThemeTargetBasePath:themeModel.curVersion];__block NSString *themeUnZipPath = [self saveThemeDirBasePath:themeModel.curVersion];__block NSString *curDownloadurl = themeModel.curDownloadurl;//下载成功NSString *afileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];__block NSString *afilePath = [NSString pathWithComponents:@[saveZipPath, afileName]];[[INHttpClientUtil sharedInstance] downloadFileURL:curDownloadurl savePath:afilePath fileName:afilePath tag:[afilePath hash] downloadProgress:^(CGFloat progress) {} success:^(NSURLResponse *response, NSString *filePath) {//下载成功NSString *fileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];NSString *selFilePath = [NSString pathWithComponents:@[saveZipPath, fileName]];//准备执行解压方法[self onFileSelected:selFilePath unZipPath:themeUnZipPath];} failure:^(HttpError *e) {NSLog(@"failure request :%@",e);}];} else {//如果存在,直接显示__block NSString *saveZipPath = [self saveThemeTargetBasePath:themeModel.curVersion];__block NSString *themeUnZipPath = [self saveThemeDirBasePath:themeModel.curVersion];__block NSString *curDownloadurl = themeModel.curDownloadurl;//下载成功NSString *fileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];NSString *filePath = [NSString pathWithComponents:@[saveZipPath, fileName]];//准备执行解压方法[self unzipCompltion:themeUnZipPath];}

2.2 解压zip主题包

将下载的主题包解压,zip包进行解压。

// 解压
- (void)releaseZipFilesWithUnzipFileAtPath:(NSString *)zipPath destination:(NSString *)unzipPath {NSError *error;// 如果解压成功if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:YES password:nil error:&error delegate:self]) {// 存储主题的色调[self unzipCompltion:unzipPath];} else {NSLog(@"%@",error);}
}

解压完成后得到解压的目录。

2.3 获取到解压的目录地址,将配置的json文件转成对应的model

获取到解压的目录地址,将配置的json文件转成对应的model

/**调用解压文件@param unzipPath 获取地址*/
- (void)unzipCompltion:(NSString *)unzipPath {// 存储主题的色调// 已经存储主题tabbar图片、navigationbar图片、配置文件等等资源NSArray *folders = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:unzipPath error:NULL];NSString *selectedFilePath = unzipPath;NSString *aPath = [folders lastObject];NSString *fullPath = [unzipPath stringByAppendingPathComponent:aPath];selectedFilePath = fullPath;NSString *configPath = [NSString stringWithFormat:@"%@/config.json",selectedFilePath];NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:configPath];NSData *data = [fh readDataToEndOfFile];NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:[SDJsonUtil dictionaryWithJsonString:jsonStr]];NSLog(@"theme config.json:%@",dict);SDAppThemeConfigViewModel *themeViewModel = [SDAppThemeConfigViewModel themeViewModel:jsonStr];themeViewModel.t_globalImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.globalImage];themeViewModel.navigation.t_backgroundImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.navigation.backgroundImage];themeViewModel.tabbar.t_backgroundImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.backgroundImage];themeViewModel.tabbar.lianlian.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.lianlian.icon];themeViewModel.tabbar.lianlian.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.lianlian.selectedIcon];themeViewModel.tabbar.guangguang.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.guangguang.icon];themeViewModel.tabbar.guangguang.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.guangguang.selectedIcon];themeViewModel.tabbar.message.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.message.icon];themeViewModel.tabbar.message.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.message.selectedIcon];themeViewModel.tabbar.mine.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.mine.icon];themeViewModel.tabbar.mine.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.mine.selectedIcon];//配置全局主题[SDAppThemeManager shareInstance].configViewModel = themeViewModel;[[NSNotificationCenter defaultCenter] postNotificationName:K_APP_THEME_CHANGED object:nil userInfo:nil];
}

之后通知界面切换对应的图片及风格图。

2.4 界面添加通知Observer

界面接收到通知后,更新到对应的图片及颜色。
我这里是就写一个切换Tabbar新年主题风格图片。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(systemAppThemeChanged:) name:K_APP_THEME_CHANGED object:nil];

切换Tabbar新年主题风格图片

- (void)updateThemeConfig {//主题,可以更改tabbar样式SDAppThemeConfigViewModel *themeConfigViewModel = [SDAppThemeManager shareInstance].configViewModel;UIImage *backgroundImage;if (themeConfigViewModel.tabbar.t_backgroundImage) {backgroundImage = themeConfigViewModel.tabbar.t_backgroundImage;} else {NSString *bgColor = themeConfigViewModel.tabbar.backgroundColor;backgroundImage = [UIImage imageWithColor:[UIColor colorWithHexString:bgColor] size:CGSizeMake(20.0, 20.0)];backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:backgroundImage.leftCapWidth*0.5 topCapHeight:backgroundImage.topCapHeight*0.5];}self.sdTabbar.bgroundImage = backgroundImage;NSString *showLine = themeConfigViewModel.tabbar.showLine;self.sdTabbar.showLine = [showLine boolValue];self.sdTabbar.lineColor = [UIColor colorWithHexString:themeConfigViewModel.tabbar.lineColor];UIColor *badgeBGColor = [UIColor colorWithHexString:themeConfigViewModel.tabbar.badgeBgColor];SDTabbarItem *homeItem = [self themeTabbarItem:themeConfigViewModel.tabbar.lianlian];homeItem.identifier = @"home";homeItem.badgeColor = badgeBGColor;SDTabbarItem *addressbookItem = [self themeTabbarItem:themeConfigViewModel.tabbar.message];addressbookItem.identifier = @"addressbook";addressbookItem.badgeColor = badgeBGColor;SDTabbarItem *discoveryItem = [self themeTabbarItem:themeConfigViewModel.tabbar.guangguang];discoveryItem.identifier = @"discovery";discoveryItem.badgeColor = badgeBGColor;SDTabbarItem *mineItem = [self themeTabbarItem:themeConfigViewModel.tabbar.mine];mineItem.identifier = @"mine";mineItem.badgeColor = badgeBGColor;[self.sdTabbar updateTabbarStyle:homeItem];[self.sdTabbar updateTabbarStyle:addressbookItem];[self.sdTabbar updateTabbarStyle:discoveryItem];[self.sdTabbar updateTabbarStyle:mineItem];
}- (void)systemAppThemeChanged:(NSNotification *)notification {[self updateThemeConfig];
}- (SDTabbarItem *)themeTabbarItem:(SDAppThemeConfigTabItemViewModel *)itemViewModel {SDTabbarItem *tabbarItem = [[SDTabbarItem alloc] init];tabbarItem.title = itemViewModel.title;tabbarItem.titleColor = [UIColor colorWithHexString:itemViewModel.titleColor];tabbarItem.selectedTitleColor = [UIColor colorWithHexString:itemViewModel.selectedTitleColor];tabbarItem.image = itemViewModel.t_icon;tabbarItem.selectedImage = itemViewModel.t_selectedIcon;return tabbarItem;
}

tabbar的按钮更新:根据对应的identifier切换到对应的图片及颜色配置。

/**更新tabbar样式@param tabbarItem item*/
- (void)updateTabbarStyle:(SDTabbarItem *)tabbarItem {for (UIView *subView in self.subviews) {if ([subView isKindOfClass:[SDTabbarButton class]]) {SDTabbarButton *tabbarButton = (SDTabbarButton *)subView;SDTabbarItem *item = tabbarButton.tabbarItem;if (tabbarItem.identifier && [tabbarItem.identifier isEqualToString:item.identifier]) {//更新tabbar[item copyClone:tabbarItem];tabbarButton.tabbarItem = item;break;}}}
}

三、将model序列化存储到本地目录

将主题数据序列号存储到本地目录,方便下次打开APP进行获取。

SDAppThemeConfigDbManager.h

#import <Foundation/Foundation.h>
#import "SDAppThemeManager.h"@interface SDAppThemeConfigDbManager : NSObject+ (id)shareInstance;- (SDAppThemeViewModel *)getAppThemeViewModelFromDb;- (void)saveAppThemeViewModelToDb:(SDAppThemeViewModel *)info;@end

SDAppThemeConfigDbManager.m

#import "SDAppThemeConfigDbManager.h"static NSString *appThemeConfigPath = @"sdAppThemeConfigPath";
static SDAppThemeConfigDbManager *instance = nil;@implementation SDAppThemeConfigDbManager+ (id)shareInstance
{static dispatch_once_t predicate;dispatch_once(&predicate,^{instance = [[self alloc] init];});return instance;
}- (NSString *)getAppThemeConfigPath
{NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentPath = [paths objectAtIndex:0];NSString *path = [documentPath stringByAppendingPathComponent:appThemeConfigPath];return path;
}- (SDAppThemeViewModel *)getAppThemeViewModelFromDb {NSString *dataFile = [self getAppThemeConfigPath];@try {SDAppThemeViewModel *viewModel = [NSKeyedUnarchiver unarchiveObjectWithFile:dataFile];if (viewModel) {return viewModel;}} @catch (NSException *e) {}return nil;
}- (void)saveAppThemeViewModelToDb:(SDAppThemeViewModel *)info {NSData *data = [NSKeyedArchiver archivedDataWithRootObject:info];NSString *dataFile = [self getAppThemeConfigPath];BOOL isSave = [data writeToFile:dataFile atomically:YES];if (isSave) {NSLog(@"存储成功");} else {NSLog(@"存储失败");}
}@end

四、完整实现代码

  • 需要用到主题Manager:SDAppThemeManager

SDAppThemeManager.h

#import <Foundation/Foundation.h>
//#import "SDThemeConfigRequest.h"
#import "SDAppThemeConfigViewModel.h"/**获取的app主题model,app主题颜色版本号*/
@interface SDAppThemeViewModel : NSObject<NSCoding>@property (nonatomic, strong) NSString *curDownloadurl;     //当前版本的下载地址
@property (nonatomic, strong) NSString *curVersion;         //当前app主题颜色版本号@property (nonatomic, strong) NSString *nextDownloadurl;    //下一版本的下载地址
@property (nonatomic, strong) NSString *nextVersion;        //下一版本app主题颜色版本号@end@interface SDAppThemeManager : NSObject+ (instancetype)shareInstance;@property (nonatomic, strong) SDAppThemeConfigViewModel *configViewModel; //当前版本控制文件/**从服务器端加载APP主题接口*/
- (void)loadAppThemeConfig;/**加载系统主题资源*/
- (void)loadCacheThemeResource;@end

SDAppThemeManager.m

#import "SDAppThemeManager.h"
#import "SDAppThemeConfigDbManager.h"
#import "SDAppThemeDownloadManager.h"
#import "INHttpClientUtil.h"@implementation SDAppThemeViewModel- (id)init {self = [super init];if (self) {}return self;
}- (id)initWithCoder:(NSCoder *)aDecoder
{self = [super init];if (self) {self.curDownloadurl = [aDecoder decodeObjectForKey:@"kAppThemeCurDownloadurl"];self.curVersion = [aDecoder decodeObjectForKey:@"kAppThemeCurVersion"];self.nextDownloadurl = [aDecoder decodeObjectForKey:@"kAppThemeNextDownloadurl"];self.nextVersion = [aDecoder decodeObjectForKey:@"kAppThemeNextVersion"];}return self;
}- (void)encodeWithCoder:(NSCoder *)aCoder
{[aCoder encodeObject:_curDownloadurl forKey:@"kAppThemeCurDownloadurl"];[aCoder encodeObject:_curVersion forKey:@"kAppThemeCurVersion"];[aCoder encodeObject:_nextDownloadurl forKey:@"kAppThemeNextDownloadurl"];[aCoder encodeObject:_nextVersion forKey:@"kAppThemeNextVersion"];
}- (void)clear {self.curDownloadurl = nil;self.curVersion = nil;self.nextDownloadurl = nil;self.nextVersion = nil;
}@endstatic SDAppThemeManager *shareInstance = nil;@implementation SDAppThemeManager+ (instancetype)shareInstance {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{shareInstance = [[SDAppThemeManager alloc] init];shareInstance.configViewModel = [SDAppThemeConfigViewModel defautThemeViewModel];});return shareInstance;
}/**从服务器端加载APP主题接口*/
- (void)loadAppThemeConfig {[[INHttpClientUtil sharedInstance] getWithClientType:HttpClientTypeDefault url:@"/v1/api/theme/system" params:nil success:^(id responseObj) {NSString *code = [NSString stringWithFormat:@"%@",responseObj[@"code"]];if ([@"0" isEqualToString:code] && responseObj[@"data"]) {NSString *curDownloadurl = responseObj[@"data"][@"curDownloadurl"];NSString *curVersion = responseObj[@"data"][@"curVersion"];NSString *nextDownloadurl = responseObj[@"data"][@"nextDownloadurl"];NSString *nextVersion = responseObj[@"data"][@"nextVersion"];SDAppThemeViewModel *themeViewModel = [[SDAppThemeViewModel alloc] init];themeViewModel.curDownloadurl = nextDownloadurl;themeViewModel.curVersion = @"2016.10.27";themeViewModel.nextDownloadurl = nextDownloadurl;themeViewModel.nextVersion = nextVersion;[[SDAppThemeConfigDbManager shareInstance] saveAppThemeViewModelToDb:themeViewModel];[[SDAppThemeDownloadManager shareInstance] downloadThemeZipPackage:themeViewModel];}} failure:^(HttpError *e) {DLog(@"request:%@",e);}];
}/**加载系统主题资源*/
- (void)loadCacheThemeResource {[[SDAppThemeDownloadManager shareInstance] loadCacheThemeResource];
}@end
  • 需要用到主题下载类SDAppThemeDownloadManager

SDAppThemeDownloadManager.h

#import <Foundation/Foundation.h>
//#import "SDThemeConfigRequest.h"
#import "SDAppThemeManager.h"
#import "SDAppThemeConfigViewModel.h"
#import "SDAppThemeConfigDbManager.h"#define K_APP_THEME_CHANGED @"K_APP_THEME_CHANGED"
#define K_DEFAULT_APP_THEME_VERSION @"1.0.0"@interface SDAppThemeDownloadManager : NSObject+ (instancetype)shareInstance;- (void)downloadThemeZipPackage:(SDAppThemeViewModel *)themeModel;/**加载系统主题资源*/
- (void)loadCacheThemeResource;@end

SDAppThemeDownloadManager.m

#import "SDAppThemeDownloadManager.h"
#import "SDJsonUtil.h"
//#import "NSString+ext.h"
#import <SSZipArchive/SSZipArchive.h>
#import "SDAppThemeManager.h"
#import "INHttpClientUtil.h"static SDAppThemeDownloadManager *manager = nil;@interface SDAppThemeDownloadManager () <SSZipArchiveDelegate>@end@implementation SDAppThemeDownloadManager+ (instancetype)shareInstance {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{manager = [[SDAppThemeDownloadManager alloc] init];});return manager;
}- (void)downloadThemeZipPackage:(SDAppThemeViewModel *)themeModel {//判断当前主题版本号下是否存在资源文件夹BOOL curThemeExist = [self hasAppThemeVersion:themeModel.curVersion];if (!curThemeExist) {//如果不存在,重新下载解压__block NSString *saveZipPath = [self saveThemeTargetBasePath:themeModel.curVersion];__block NSString *themeUnZipPath = [self saveThemeDirBasePath:themeModel.curVersion];__block NSString *curDownloadurl = themeModel.curDownloadurl;//下载成功NSString *afileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];__block NSString *afilePath = [NSString pathWithComponents:@[saveZipPath, afileName]];[[INHttpClientUtil sharedInstance] downloadFileURL:curDownloadurl savePath:afilePath fileName:afilePath tag:[afilePath hash] downloadProgress:^(CGFloat progress) {} success:^(NSURLResponse *response, NSString *filePath) {//下载成功NSString *fileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];NSString *selFilePath = [NSString pathWithComponents:@[saveZipPath, fileName]];//准备执行解压方法[self onFileSelected:selFilePath unZipPath:themeUnZipPath];} failure:^(HttpError *e) {NSLog(@"failure request :%@",e);}];} else {//如果存在,直接显示__block NSString *saveZipPath = [self saveThemeTargetBasePath:themeModel.curVersion];__block NSString *themeUnZipPath = [self saveThemeDirBasePath:themeModel.curVersion];__block NSString *curDownloadurl = themeModel.curDownloadurl;//下载成功NSString *fileName = [[NSURL URLWithString:curDownloadurl] lastPathComponent];NSString *filePath = [NSString pathWithComponents:@[saveZipPath, fileName]];//准备执行解压方法[self unzipCompltion:themeUnZipPath];}/*//判断下一主题版本号下是否存在资源文件夹中BOOL nextThemeExist = [self hasAppThemeVersion:themeModel.nextVersion];if (!nextThemeExist) {//如果不存在,重新下载解压__block NSString *saveZipPath = [self saveThemeTargetBasePath:themeModel.nextVersion];[[HttpClient sharedInstance] downloadFileURL:themeModel.curDownloadurl savePath:saveZipPath fileName:saveZipPath tag:[saveZipPath hash] success:^(id responseObj) {//下载成功} failure:^(HttpException *e) {//下载失败}];}*/
}// 解压
- (void)releaseZipFilesWithUnzipFileAtPath:(NSString *)zipPath destination:(NSString *)unzipPath {NSError *error;// 如果解压成功if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:YES password:nil error:&error delegate:self]) {// 存储主题的色调[self unzipCompltion:unzipPath];} else {NSLog(@"%@",error);}
}/**调用解压文件@param unzipPath 获取地址*/
- (void)unzipCompltion:(NSString *)unzipPath {// 存储主题的色调// 已经存储主题tabbar图片、navigationbar图片、配置文件等等资源NSArray *folders = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:unzipPath error:NULL];NSString *selectedFilePath = unzipPath;NSString *aPath = [folders lastObject];NSString *fullPath = [unzipPath stringByAppendingPathComponent:aPath];selectedFilePath = fullPath;NSString *configPath = [NSString stringWithFormat:@"%@/config.json",selectedFilePath];NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:configPath];NSData *data = [fh readDataToEndOfFile];NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:[SDJsonUtil dictionaryWithJsonString:jsonStr]];NSLog(@"theme config.json:%@",dict);SDAppThemeConfigViewModel *themeViewModel = [SDAppThemeConfigViewModel themeViewModel:jsonStr];themeViewModel.t_globalImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.globalImage];themeViewModel.navigation.t_backgroundImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.navigation.backgroundImage];themeViewModel.tabbar.t_backgroundImage = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.backgroundImage];themeViewModel.tabbar.lianlian.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.lianlian.icon];themeViewModel.tabbar.lianlian.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.lianlian.selectedIcon];themeViewModel.tabbar.guangguang.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.guangguang.icon];themeViewModel.tabbar.guangguang.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.guangguang.selectedIcon];themeViewModel.tabbar.message.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.message.icon];themeViewModel.tabbar.message.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.message.selectedIcon];themeViewModel.tabbar.mine.t_icon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.mine.icon];themeViewModel.tabbar.mine.t_selectedIcon = [self imageWithDocumentoryName:[NSString stringWithFormat:@"%@",selectedFilePath] imageName:themeViewModel.tabbar.mine.selectedIcon];//配置全局主题[SDAppThemeManager shareInstance].configViewModel = themeViewModel;[[NSNotificationCenter defaultCenter] postNotificationName:K_APP_THEME_CHANGED object:nil userInfo:nil];
}/**准备执行解压方法@param selectedPath 原先文件路径@param unZipPath 解压文件路径*/
- (void)onFileSelected:(NSString *)selectedPath unZipPath:(NSString *)unZipPath {NSURL *fileURL = [NSURL fileURLWithPath:selectedPath];NSString *fileNameComponent = fileURL.lastPathComponent;// 获取文件的扩展名NSString *extension = [[fileNameComponent pathExtension] lowercaseString];// 如果是zip类型的压缩包文件,则进行解压if ([extension isEqualToString:@"zip"]) {// 设置解压路径[self releaseZipFilesWithUnzipFileAtPath:selectedPath destination:unZipPath];}
}/**判断当前path路径是否存在@param themeVersion 主题版本号@return 是否文件*/
- (BOOL)hasAppThemeVersion:(NSString *)themeVersion {NSString *pathOfLibrary = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];NSString *path = [pathOfLibrary stringByAppendingPathComponent:[NSString stringWithFormat:@"dftheme-%@",themeVersion]];NSArray *folders = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];if (!(folders && folders.count > 0)) {return NO;}NSString *aPath = [folders lastObject];NSString *fullPath = [path stringByAppendingPathComponent:aPath];NSFileManager *fileManager = [NSFileManager defaultManager];BOOL result = [fileManager fileExistsAtPath:fullPath];return result;
}/**主题未解压下载目录@param themeVersion 主题版本号@return 最后path*/
- (NSString *)saveThemeTargetBasePath:(NSString *)themeVersion {NSString *pathOfLibrary = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];NSString *path = [pathOfLibrary stringByAppendingPathComponent:[NSString stringWithFormat:@"dfThemesZip-%@",themeVersion]];[self createDirectory:path];return path;
}/**主题解压目录@param themeVersion 主题版本号@return 最后path*/
- (NSString *)saveThemeDirBasePath:(NSString *)themeVersion {NSString *pathOfLibrary = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];NSString *path = [pathOfLibrary stringByAppendingPathComponent:[NSString stringWithFormat:@"dftheme-%@",themeVersion]];[self createDirectory:path];return path;
}- (void)createDirectory:(NSString *)path {NSError *error = nil;[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YESattributes:nil error:&error];if (error) {NSLog(@"Create directory error: %@", error);}
}/**获取使用存储在沙盒里的图片@param documentoryName 文件目录@param imageName 图片名字@return 图片*/
- (UIImage *)imageWithDocumentoryName:(NSString *)documentoryNameimageName:(NSString *)imageName {// 如果文件名不存在或者文件名为空,则返回空if (!imageName || [imageName isEqualToString:@""]) {return nil;}NSString *imgPath = [documentoryName stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",imageName]];UIImage *image = [UIImage imageWithContentsOfFile:imgPath];if (image) {return image;}return [UIImage imageNamed:imageName];
}/**加载系统主题资源*/
- (void)loadCacheThemeResource {SDAppThemeViewModel *themeVersionViewModel = [[SDAppThemeConfigDbManager shareInstance] getAppThemeViewModelFromDb];if (themeVersionViewModel && ![K_DEFAULT_APP_THEME_VERSION isEqualToString:themeVersionViewModel.curVersion]) {[self downloadThemeZipPackage:themeVersionViewModel];}
}

@end

  • 需要用到主题数据:SDAppThemeConfigViewModel

SDAppThemeConfigViewModel.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>/**Navigation主题样式*/
@interface SDAppThemeConfigNavViewModel : NSObject@property (nonatomic, strong) NSString *backgroundColor;
@property (nonatomic, strong) NSString *backgroundImage;@property (nonatomic, strong) UIImage *t_backgroundImage;@property (nonatomic, strong) NSString *btnImageColor;
@property (nonatomic, strong) NSString *btnTitleColor;
@property (nonatomic, strong) NSString *navTitleColor;@property (nonatomic, strong) NSString *showLine;
@property (nonatomic, strong) NSString *lineColor;@end/**单个tab按钮样式*/
@interface SDAppThemeConfigTabItemViewModel : NSObject@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *titleColor;
@property (nonatomic, strong) NSString *selectedTitleColor;
@property (nonatomic, strong) NSString *icon;
@property (nonatomic, strong) NSString *selectedIcon;@property (nonatomic, strong) UIImage *t_icon;
@property (nonatomic, strong) UIImage *t_selectedIcon;@end/**tabbar样式*/
@interface SDAppThemeConfigTabViewModel : NSObject@property (nonatomic, strong) NSString *backgroundColor;
@property (nonatomic, strong) NSString *backgroundImage;
@property (nonatomic, strong) NSString *showLine;
@property (nonatomic, strong) NSString *lineColor;
@property (nonatomic, strong) NSString *badgeBgColor;@property (nonatomic, strong) UIImage *t_backgroundImage;@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *lianlian;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *guangguang;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *message;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *shop;
@property (nonatomic, strong) SDAppThemeConfigTabItemViewModel *mine;@end/**将本地的主题config.json转成viewmodel*/
@interface SDAppThemeConfigViewModel : NSObject@property (nonatomic, strong) NSString *globalColor;
@property (nonatomic, strong) NSString *globalImage;
@property (nonatomic, strong) SDAppThemeConfigNavViewModel *navigation;
@property (nonatomic, strong) SDAppThemeConfigTabViewModel *tabbar;@property (nonatomic, strong) UIImage *t_globalImage;+ (SDAppThemeConfigViewModel *)themeViewModel:(NSString *)themeJson;+ (SDAppThemeConfigViewModel *)defautThemeViewModel;@end

SDAppThemeConfigViewModel.m

#import "SDAppThemeConfigViewModel.h"
#import <NSObject+YYModel.h>/**Navigation主题样式*/
@implementation SDAppThemeConfigNavViewModel@end/**单个tab按钮样式*/
@implementation SDAppThemeConfigTabItemViewModel@end/**tabbar样式*/
@implementation SDAppThemeConfigTabViewModel@end/**将本地的主题config.json转成viewmodel*/
@implementation SDAppThemeConfigViewModel+ (SDAppThemeConfigViewModel *)themeViewModel:(NSString *)themeJson {return [SDAppThemeConfigViewModel modelWithJSON:themeJson];
}+ (SDAppThemeConfigViewModel *)defautThemeViewModel {SDAppThemeConfigViewModel *viewModel = [[SDAppThemeConfigViewModel alloc] init];SDAppThemeConfigNavViewModel *navConfigViewModel = [[SDAppThemeConfigNavViewModel alloc] init];navConfigViewModel.backgroundColor = @"171013";navConfigViewModel.btnImageColor = @"ffffff";navConfigViewModel.btnTitleColor = @"ffffff";navConfigViewModel.navTitleColor = @"ffffff";viewModel.navigation = navConfigViewModel;return viewModel;
}@end
  • 主题配置序列化存储本地:SDAppThemeConfigDbManager

SDAppThemeConfigDbManager.h

#import <Foundation/Foundation.h>
#import "SDAppThemeManager.h"@interface SDAppThemeConfigDbManager : NSObject+ (id)shareInstance;- (SDAppThemeViewModel *)getAppThemeViewModelFromDb;- (void)saveAppThemeViewModelToDb:(SDAppThemeViewModel *)info;@end

SDAppThemeConfigDbManager.m

#import "SDAppThemeConfigDbManager.h"static NSString *appThemeConfigPath = @"sdAppThemeConfigPath";
static SDAppThemeConfigDbManager *instance = nil;@implementation SDAppThemeConfigDbManager+ (id)shareInstance
{static dispatch_once_t predicate;dispatch_once(&predicate,^{instance = [[self alloc] init];});return instance;
}- (NSString *)getAppThemeConfigPath
{NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentPath = [paths objectAtIndex:0];NSString *path = [documentPath stringByAppendingPathComponent:appThemeConfigPath];return path;
}- (SDAppThemeViewModel *)getAppThemeViewModelFromDb {NSString *dataFile = [self getAppThemeConfigPath];@try {SDAppThemeViewModel *viewModel = [NSKeyedUnarchiver unarchiveObjectWithFile:dataFile];if (viewModel) {return viewModel;}} @catch (NSException *e) {}return nil;
}- (void)saveAppThemeViewModelToDb:(SDAppThemeViewModel *)info {NSData *data = [NSKeyedArchiver archivedDataWithRootObject:info];NSString *dataFile = [self getAppThemeConfigPath];BOOL isSave = [data writeToFile:dataFile atomically:YES];if (isSave) {NSLog(@"存储成功");} else {NSLog(@"存储失败");}
}@end

至此,实现获取下载主题配置更切换主题的代码实现完成。

五、小结

iOS开发-实现获取下载主题配置更切换主题,主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。

学习记录,每天不停进步。

相关文章:

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题 iOS开发-实现获取下载主题配置更切换主题&#xff0c;主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。 比如新年主题风格&#xff0c;常见的背景显示红色氛围图片、tabbar显示新…...

react经验4:动态组件

什么是动态组件&#xff1f; 在页面的一小块区域切换显示不同的组件 实现方法 1.声明示例组件 //写在component1.tsx中 const Component1()>{return (<div>组件1</div>) } //写在component2.tsx中 const Component2()>{return (<div>组件2</div…...

Java maven的下载解压配置(保姆级教学)

mamen基本概念 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性&#xff0c;所以…...

Java课题笔记~数据库连接池

一、数据库连接池 1.1 数据库连接池简介 数据库连接池是个容器&#xff0c;负责分配、管理数据库连接(Connection) 它允许应用程序重复使用一个现有的数据库连接&#xff0c;而不是再重新建立一个&#xff1b; 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数…...

设计模式-单例模式

文章目录 单例模式饿汉式单例懒汉式单例懒汉式加锁单例双重锁校验单例静态内部类单例枚举单例 单例模式 单例模式主要是确保一个类在任何情况下都只有一个实例&#xff0c;并提供一个全局访问的点。 主要有以下几种 饿汉式单例 /*** 饿汉式* 类加载到内存后&#xff0c;就实…...

golang mysql

驱动 "github.com/go-sql-driver/mysql"使用到的方法 func sql.Open(driverName string, dataSourceName string) (*sql.DB, error) func (*sql.DB).Prepare(query string) (*sql.Stmt, error)//使用DB.Prepare预编译并使用参数化查询&#xff0c;对预编译的SQL语句…...

uniapp使用echarts

uniapp使用echarts 1.下载资源包2.引入资源包3.代码示例注意事项 1.下载资源包 https://echarts.apache.org/zh/download.html 2.引入资源包 将资源包放入项目内 3.代码示例 <template><div style"width:100%;height:500rpx" id"line" ref&…...

Python命令模式介绍、使用

一、Python命令模式介绍 Python命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许将请求或操作封装在对象中&#xff0c;并将其作为参数传递给调用对象&#xff0c;以在不同的环境中执行相同的请求或操作。 功能&#xff1a; 将请求或…...

#typescript 使用file-saver模块#

场景&#xff1a;前端使用file-saver模块做导出文档的时候&#xff0c;出现两个错误 1&#xff1a;npm run build 提示找不到模块&#xff0c;如图 解决方法&#xff1a; 先卸载&#xff0c;不管是否安装都先要卸载 ,然后安装&#xff1a; npm uninstall file-saver npm…...

移动端适配布局rem和vw

在日益发展的移动互联网时代&#xff0c;作为前端开发者&#xff0c;我们必须了解和掌握各种移动端显示效果的适配技术。在众多适配方案中&#xff0c;使用rem和vw进行布局是当前最为流行和普遍使用的两种技术。通过合理运用这两种技术&#xff0c;我们可以让我们的网页在不同尺…...

【Java基础教程】(四十八)集合体系篇 · 上:全面解析 Collection、List、Set常用子接口及集合元素迭代遍历方式~【文末送书】

Java基础教程之集合体系 上 &#x1f539;本章学习目标1️⃣ 类集框架介绍2️⃣ 单列集合顶层接口&#xff1a;Collection3️⃣ List 子接口3.1 ArrayList 类&#x1f50d; 数组&#xff08;Array&#xff09;与列表&#xff08;ArrayList&#xff09;有什么区别?3.2 LinkedL…...

什么是 DNS ANAME 解析?

本人使用谷歌搜索了简中互联网&#xff0c;完全没有找到任何有关 ANAME 的文章……本文该不会是头一份吧 相信大家对于 DNS 的解析方式都不陌生&#xff0c;常见的有 A、CNAME、MX、TXT 记录等等。其中&#xff0c;网站常用的是 A 记录和 CNAME 记录&#xff1a;A 记录用于将域…...

Neo4j 集群和负载均衡

Neo4j 集群和负载均衡 Neo4j是当前最流行的开源图DB。刚好读到了Neo4j的集群和负载均衡策略&#xff0c;记录一下。 1 集群 Neo4j 集群使用主从复制实现高可用性和水平读扩展。 1.1 复制 集群的写入都通过主节点协调完成的&#xff0c;数据先写入主机&#xff0c;再同步到…...

go web框架 gin-gonic源码解读01————Engine

go web框架 gin-gonic源码解读01————Engine gin-gonic是go语言开发的轻量级web框架&#xff0c;性能优异&#xff0c;代码简洁&#xff0c;功能强大。有很多值得学习的地方,最近准备把这段时间学习gin的知识点&#xff0c;通过engine&#xff0c;context&#xff0c;router…...

windows版docker部署springcloud项目

材料&#xff1a; 1.windows版docker环境&#xff08;其他版教程可能道理一样但是比如文件后坠名上可能有差异&#xff09; 2.运行好的数据库容器&#xff08;实现教程&#xff09; 3.所有jar包 实现&#xff1a; 最后整好的文件夹结构图&#xff08;原工程文件机密&#xf…...

探索工程机械远程控制新纪元:Intewell-Hyper II震撼发布!

在当前的工程技术领域&#xff0c;远程控制技术以其卓越的效率和方便性&#xff0c;正受到越来越多的关注和运用。而在这个过程中&#xff0c;某机械集团以Intewell-HyperII操作系统为基础&#xff0c;打造出了具有前瞻性的工程机械远程控制器&#xff0c;为行业的发展提供了新…...

DM8 DSC集群实时主备搭建

1、环境准备 主库DSC集群公网ip&#xff1a;192.168.1.34/35 私有ip&#xff1a;192.168.10.134/135 备库ip&#xff1a;192.168.1.33 2、对DSC集群数据库全备 1)主库做全备 [dmdbadmdsc01 bin]$ disql sysdba/dameng123 BACKUP DATABASE TO WEEKLY_FULL_BAK BACKUPSE…...

配置IPv4 over IPv6隧道示例

IPv4 over IPv6隧道&#xff1a; 在IPv4 Internet向IPv6 Internet过渡后期&#xff0c;IPv6网络被大量部署后&#xff0c;而IPv4网络只是散布在世界各地的一些孤岛。利用隧道技术可以在IPv6网络上创建隧道&#xff0c;从而实现IPv4孤岛的互联&#xff0c;IPv4孤岛能通过IPv6公…...

在中国区部署日志通2.0

前提条件 一个域名&#xff1a;使用此域名来访问日志通控制台提供aws iam 的ssl证书 &#xff0c;而且必须跟域名相关联具有四个子网&#xff08;两个公有子网和两个私有子网&#xff09;和NAT网关的VPC 步骤 1.创建ACM证书 1.1 请求公有证书 1.2 配置域名 1.3 新申请的证书记…...

centos下安装jdk

环境:centos7/openjdk-8u40-b25 openJDK页面 java二进制包下载页面 华为jdk镜像 1.下载安装包后上传到服务器上&#xff0c;运行命令解压到/opt/目录下 tar cxvf server-jre-8u271-linux-x64.tar.gz -C /opt/2.配置环境变量 vi /etc/profile source /etc/profile添加下面的…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...