由于现在经常出现撤县建市,裁撤乡村,大城市把撤县设区以及区划调整,所以需要更新省市区的数据。
解决办法是后台从民政部获取官方省市区数据,录入数据库。后台增加接口让前端调用,获取实时省市区实时数据。
由于省市区数据超过4000条记录,数据量极大,这种实时获取的方式十分费时间和流量。所以要做本地化处理。
把省市区版本号存入系统plist文件([[NSUserDefaults standardUserDefaults] objectForKey:key]),应用启动时,判断版本号是否一致,若不一致清除本地数据,若一致加载本地化数据放入内存,以便于有获取省市区。
在使用的页面判断内存中是否有省市区数据,若没有就调用省市区接口并本地化数据。
当然你若认为把省市区本地化数据加载如内存浪费内存,也使用时获取就可以。一般的手机内存都很大,也不在乎那几百k的内存。
BGChinaAddressEntity.h
#import
@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;
BGChinaAddressEntity.m
#import
@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
//日志文档目录,若定义就把日志存在NSDocumentDirectory目录下,若不定义就存在NSCachesDirectory目录下
#define
#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
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
//加载我的订单和行程列表本地数据
-(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];
}
序列化后的省市区三级联动文件。