iOS项目中经常遇到数据的存储,NSArray、NSDictionary、NSString等等遵循了NSCopying协议的数据模型可以直接存储到本地,但是如果我是自定义的模型怎么办呢?
OC中有很多方式能够实现,但是今天我们说一个不需要借助于第三方的方式来实现:归档操作来存储。直接用归档方法,实现不了存储。这个时候我们可以通过遵守<NSCopying>协议来编码对象和解码对象操作
1、模型的 .h
#import <Foundation/Foundation.h>
@interface SmartCityModel : NSObject
@property (nonatomic, copy) NSString *cityName; //名称 北京市
@property (nonatomic, copy) NSString *initial; //首字母 bjs
@property (nonatomic, copy) NSString *citySpell; //拼音 beijingshi
@property (nonatomic, copy) NSString *firstCharacter; //b
@property (nonatomic, copy) NSString *secondCharacter; //j
@property (nonatomic, copy) NSString *thirdCharacter; //s
@end
2、模型的 .m
#import "SmartCityModel.h"
@implementation SmartCityModel
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.cityName forKey:@"cityName"];
[aCoder encodeObject:self.initial forKey:@"initial"];
[aCoder encodeObject:self.citySpell forKey:@"citySpell"];
[aCoder encodeObject:self.firstCharacter forKey:@"firstCharacter"];
[aCoder encodeObject:self.secondCharacter forKey:@"secondCharacter"];
[aCoder encodeObject:self.thirdCharacter forKey:@"thirdCharacter"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.cityName = [aDecoder decodeObjectForKey:@"cityName"];
self.initial = [aDecoder decodeObjectForKey:@"initial"];
self.citySpell = [aDecoder decodeObjectForKey:@"citySpell"];
self.firstCharacter = [aDecoder decodeObjectForKey:@"firstCharacter"];
self.secondCharacter = [aDecoder decodeObjectForKey:@"secondCharacter"];
self.thirdCharacter = [aDecoder decodeObjectForKey:@"thirdCharacter"];
}
return self;
}
@end
3、后面就可以直接使用这个模型(在这里我是把城市字符串转成城市模型)
//获取汉字转成拼音字符串 通讯录模糊搜索 支持拼音检索 首字母 全拼 汉字 搜索
+ (SmartCityModel *)transformToPinyin:(NSString *)aString
{
SmartCityModel *model = [[SmartCityModel alloc] init];
//转成了可变字符串
NSMutableString *str = [NSMutableString stringWithString:aString];
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
//再转换为不带声调的拼音
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformStripDiacritics,NO);
NSArray *pinyinArray = [str componentsSeparatedByString:@" "];
for (int i = 0; i < pinyinArray.count; i ++) {
NSString *subString = pinyinArray[i];
if (subString.length > 0) {
subString = [subString substringToIndex:1];
if (i == 0) {
model.firstCharacter = subString;
}else if (i == 1) {
model.secondCharacter = subString;
}else if (i == 2) {
model.thirdCharacter = subString;
}
}
}
NSMutableString *initial = [NSMutableString string];
for (NSString *s in pinyinArray){//首字母
if (s.length > 0){
[initial appendString:[s substringToIndex:1]];
}
}
model.initial = initial;
model.cityName = aString;
NSMutableString *spell = [NSMutableString string];
for (NSString *s in pinyinArray){//拼音
[spell appendString:s];
}
model.citySpell = spell;
return model;
}
4、缓存到本地时使用归档[NSKeyedArchiver archivedDataWithRootObject:];
转成NSData来存储
+(void)cacheLocalRegion
{
NSMutableArray *localRegionArray = @[].mutableCopy;
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSData *regionData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"region" ofType:@"json"]];
NSError *error = nil;
id reponse = [NSJSONSerialization JSONObjectWithData:regionData options:NSJSONReadingMutableContainers error:&error];
if (!error) {
if ([reponse isKindOfClass:[NSArray class]]) {
NSArray *local = (NSArray *)reponse;
NSMutableArray *localCityArray = @[].mutableCopy;
for (NSDictionary *province in local) {
NSString *provinceStr = province[@"name"];
if (![localCityArray containsObject:provinceStr]) {
[localCityArray addObject:provinceStr];
}
NSArray *cityArray = province[@"city"];
for (NSDictionary *city in cityArray) {
NSString *cityStr = city[@"name"];
if (![localCityArray containsObject:cityStr]) {
[localCityArray addObject:cityStr];
}
NSArray *areaArray = city[@"area"];
for (NSString *areaStr in areaArray) {
if (![localCityArray containsObject:areaStr]) {
[localCityArray addObject:areaStr];
}
}
}
}
//转str --> 拼接字符串
for (NSString *city in localCityArray) {
[localRegionArray addObject:[NSString transformToPinyin:city]];
}
//缓存在本地
NSData *regionData = [NSKeyedArchiver archivedDataWithRootObject:localRegionArray];
[[NSUserDefaults standardUserDefaults] setValue:regionData forKey:cacheRegion];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}else{
[SmartToast Tost:@"地区解析失败"];
}
});
}
5、最后把NSData解档成存储时的数据就可以了
NSData *regonData = [[NSUserDefaults standardUserDefaults] valueForKey:cacheRegion];
NSArray *regionArray = [NSKeyedUnarchiver unarchiveObjectWithData:regonData];
网友评论