由于现在经常出现撤县建市,裁撤乡村,大城市把撤县设区以及区划调整,所以需要更新省市区的数据。
解决办法是后台从民政部获取官方省市区数据,录入数据库。后台增加接口让前端调用,获取实时省市区实时数据。
由于省市区数据超过4000条记录,数据量极大,这种实时获取的方式十分费时间和流量。所以要做本地化处理。
把省市区版本号存入系统plist文件([[NSUserDefaults standardUserDefaults] objectForKey:key]),应用启动时,判断版本号是否一致,若不一致清除本地数据,若一致加载本地化数据放入内存,以便于有获取省市区。
在使用的页面判断内存中是否有省市区数据,若没有就调用省市区接口并本地化数据。
当然你若认为把省市区本地化数据加载如内存浪费内存,也使用时获取就可以。一般的手机内存都很大,也不在乎那几百k的内存。
BGChinaAddressEntity.h
#import <UIKit/UIKit.h> @interface BGChinaAddressEntity : NSObject<NSCoding> @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *code; @property (nonatomic, strong) NSString *pcode; @property (nonatomic, strong) NSString *subFilePath; @property (nonatomic, strong) NSMutableArray *sub; -(BGChinaAddressEntity *)updateWithName:(NSString *)name code:(NSString *)code pcode:(NSString *)pcode subFilePath:(NSString *)subFilePath; @end
BGChinaAddressEntity.m
#import "BGChinaAddressEntity.h" @implementation BGChinaAddressEntity - (instancetype)init { self = [super init]; return self; } //将对象编码(即:序列化) -(void) encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:(isCommonUnitEmptyString(self.pcode)?@"":self.pcode) forKey:@"pcode"]; [aCoder encodeObject:self.code forKey:@"code"]; [aCoder encodeObject:self.subFilePath forKey:@"subFilePath"]; } // //将对象解码(反序列化) -(id) initWithCoder:(NSCoder *)aDecoder { if (self=[super init]) { self.name= [aDecoder decodeObjectForKey:@"name"]; self.pcode= [aDecoder decodeObjectForKey:@"pcode"]; self.code= [aDecoder decodeObjectForKey:@"code"]; self.subFilePath= [aDecoder decodeObjectForKey:@"subFilePath"]; } return (self); } -(BGChinaAddressEntity *)updateWithName:(NSString *)name code:(NSString *)code pcode:(NSString *)pcode subFilePath:(NSString *)subFilePath { self.name = name; self.code = code; self.pcode = pcode; self.subFilePath = subFilePath; return self; }
@property(nonatomic, assign) long long provinceCityDistrictVersion;
#ifndef LOCATION_DATA_DOCUMENT_DICRECTORY //日志文档目录,若定义就把日志存在NSDocumentDirectory目录下,若不定义就存在NSCachesDirectory目录下 #define LOCATION_DATA_DOCUMENT_DICRECTORY #endif
+(PPSingleObject *) sharedInstance { static PPSingleObject *sharedInstace = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstace = [[self alloc] init]; sharedInstace.provinceCityDistrictVersion = [BITMobilePassword valueForKey:@"provinceCityDistrictVersion"] == NULL ? 0 : [[BITMobilePassword valueForKey:@"provinceCityDistrictVersion"] longLongValue]; }); return sharedInstace; }
序列化:
- (BOOL)isDirectory:(NSString *)filePath { if(isEmptyString(filePath)) { return NO; } NSNumber *isDirectory; NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; [fileUrl getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; return isDirectory.boolValue; } - (void)storageDataModelWithPath:(NSString *)path dataArr:(NSMutableArray *)dataArr directory:(NSString *)directory { if(isCommonUnitEmptyString(path) || isCommonUnitEmptyString(directory)) { return; } if (![self isDirectory:directory]) { NSFileManager* fm = [NSFileManager defaultManager]; [fm createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil]; } if(![dataArr isKindOfClass:[NSArray class]] || (dataArr.count == 0)) { //由于已经删除了地址的根目录,不需要重新删除文件或目录 return; } NSMutableArray *arr = [NSMutableArray array]; for(NSUInteger i = 0; i < dataArr.count; i++) { BGChinaAddressEntity *model = dataArr[i]; if(![model isKindOfClass:[BGChinaAddressEntity class]]) { return; } [arr addObject:model]; } if(arr.count > 0) { NSData * tempArchive = [NSKeyedArchiver archivedDataWithRootObject:arr]; BOOL result = [tempArchive writeToFile:path atomically:YES]; // NSLog(@"result:%d", result); [BITMobilePassword setUserDefaultsValue:[NSString stringWithFormat:@"%lld", sProvinceCityDistrictVersion] key:@"provinceCityDistrictVersion"]; } } - (void)deleteAddressAllFiles { #ifdef LOCATION_DATA_DOCUMENT_DICRECTORY NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); #else NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); #endif NSFileManager* fm = [NSFileManager defaultManager]; NSString *path=[paths objectAtIndex:0]; path = [path stringByAppendingPathComponent:sAddressData]; if ([self isDirectory:path]) { [fm removeItemAtPath:path error:nil]; } }
反序列化:
-(BOOL)judgeCanUseLoadLoctaionListData { if(self.loadLoctaionListDataStaus == BGLoadLoctaionListDataStausProcessing) { if([[NSDate date] timeIntervalSince1970] - self.loadLoctaionListDataTime < LOAD_LOCATION_LIST_DATA_MAX_TIME) { return NO; } else { [self loadLoctaionData]; return YES; } } else { return YES; } } #pragma mark - 加载本地数据 //加载我的订单和行程列表本地数据 -(void)loadLocationListDataBSD { if((self.loadLoctaionListDataStaus == BGLoadLoctaionListDataStausProcessing) && ([[NSDate date] timeIntervalSince1970] - self.loadLoctaionListDataTime < LOAD_LOCATION_LIST_DATA_MAX_TIME)) { return; } self.addressArr = [NSMutableArray array]; self.loadLoctaionListDataStaus = BGLoadLoctaionListDataStausProcessing; self.loadLoctaionListDataTime = (long long)[[NSDate date] timeIntervalSince1970]; @weakify(self); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @strongify(self); [self loadLoctaionAddressData]; }); } -(void)loadLoctaionAddressData { self.loadLoctaionListDataStaus = BGLoadLoctaionListDataStausProcessing; self.loadLoctaionListDataTime = (long long)[[NSDate date] timeIntervalSince1970]; NSString *path= [self getDataDirectory]; if(!isCommonUnitEmptyString(path)) { path = [path stringByAppendingPathComponent:sAddressData]; } NSFileManager* fm = [NSFileManager defaultManager]; NSArray *dirArray1 = [fm contentsOfDirectoryAtPath:path error:nil]; // NSLog(@"dirarray1:%@ ",dirArray1); NSMutableArray *tempAddressArr1 = [NSMutableArray array]; if(!isCommonUnitEmptyArray(dirArray1)) { for(NSString *fileName in dirArray1) { if(!isCommonUnitEmptyString(fileName)) { NSString *filePath1 = [path stringByAppendingPathComponent:fileName]; NSArray *array1 = [fileName componentsSeparatedByString:@"-"]; if (array1.count==2 || array1.count==3) { NSString *name = array1[0]; NSString *code = array1[1]; NSString *pcode = [array1 objectAtSafeIndex:2]; BGChinaAddressEntity *chinaAddressEntity1 = [[BGChinaAddressEntity alloc] updateWithName:name code:code pcode:pcode subFilePath:filePath1]; [tempAddressArr1 addObject:chinaAddressEntity1]; if([self isDirectory:filePath1]) { chinaAddressEntity1.subFilePath = filePath1; NSArray *dirArray2 = [fm contentsOfDirectoryAtPath:filePath1 error:nil]; if(!isCommonUnitEmptyArray(dirArray2)) { NSMutableArray *tempAddressArr2 = [NSMutableArray array]; for(NSString *fileName2 in dirArray2) { if(!isCommonUnitEmptyString(fileName2)) { NSString *filePath2 = [filePath1 stringByAppendingPathComponent:fileName2]; NSArray *array2 = [fileName2 componentsSeparatedByString:@"-"]; if (array2.count==2 || array2.count==3) { NSString *name = array2[0]; NSString *code = array2[1]; NSString *pcode = nil;//[array2 objectAtSafeIndex:2]; if(array2.count == 3) { pcode = array2[1]; code = [array2 objectAtSafeIndex:2]; } BGChinaAddressEntity *chinaAddressEntity2 = [[BGChinaAddressEntity alloc] updateWithName:name code:code pcode:pcode subFilePath:filePath2]; [tempAddressArr2 addObject:chinaAddressEntity2]; chinaAddressEntity1.sub = tempAddressArr2; if([fm fileExistsAtPath:filePath2]) { NSData *data = [NSData dataWithContentsOfFile:filePath2];//读取文件 NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];//反序列化 if(!isCommonUnitEmptyArray(arr)) { chinaAddressEntity2.sub = arr; } } } } } } } } } } } if(!isCommonUnitEmptyArray(tempAddressArr1)) { [[PPSingleObject sharedInstance].addressArr removeAllObjects]; NSArray *dirArray1 = [tempAddressArr1 sortedArrayUsingComparator:^NSComparisonResult(BGChinaAddressEntity *obj1,BGChinaAddressEntity *obj2) { return [obj1.code compare:obj2.code options:NSNumericSearch];//正序 }]; // for(BGChinaAddressEntity *chinaAddressEntity in dirArray1) // { // [[PPSingleObject sharedInstance].addressArr addObject:chinaAddressEntity]; // } for(BGChinaAddressEntity *chinaAddressEntity in dirArray1) { if(!isCommonUnitEmptyArray(chinaAddressEntity.sub)) { NSArray *dirArray2 = [chinaAddressEntity.sub sortedArrayUsingComparator:^NSComparisonResult(BGChinaAddressEntity *obj1,BGChinaAddressEntity *obj2) { return [obj1.code compare:obj2.code options:NSNumericSearch];//正序 }]; chinaAddressEntity.sub = [[NSMutableArray alloc] initWithArray:dirArray2]; } [[PPSingleObject sharedInstance].addressArr addObject:chinaAddressEntity]; } } self.loadLoctaionListDataStaus = BGLoadLoctaionListDataStausSuccess; self.loadLoctaionListDataTime = 0;//(long long)[[NSDate date] timeIntervalSince1970]; }
序列化后的省市区三级联动文件。