衔接上两篇讲到的CoreData的使用,本篇主要介绍在实际开发中CoreData要进行二次封装,易扩展也方便使用。
创建一个继承自NSObject的类文件
- .h文件的接口
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "Student+CoreDataProperties.h"
@interface CoreDataManager : NSObject
// 放在.H 文件中,增删改查时让外部进行调用
@property(nonatomic,strong)NSManagedObjectContext *context;
+ (instancetype)shareManager;
- (BOOL)insertDataWithEntityName:(NSString *)entityName andDictionary:(NSDictionary *)dict;
- (NSArray *)selectRecordWithEntityName:(NSString *)entityName andPredicateString:(NSString *)predicateString andSortWithKeyArr:(NSArray *)sortKeyArr andAscending:(BOOL)ascending;
- (BOOL)deleteDataWithEntityName:(NSString *)entityName predicateString:(NSString *)predicateString;
- (BOOL)updateRecordWithEntityName:(NSString *)entityName andPredicateString:(NSString *)predicateString andSetAttributeDict:(NSDictionary*)dict;
@end
- .m文件中的实现
#import "CoreDataManager.h"
@interface CoreDataManager()
@property(nonatomic,readwrite,strong)NSManagedObjectModel *objModel;
@property(nonatomic,readwrite,strong)NSPersistentStoreCoordinator *persistentCoordinator;
@end
@implementation CoreDataManager
static CoreDataManager *instance;
+(instancetype)shareManager{
if(instance == nil){
instance = [[super alloc] init];
}
return instance;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone ];
});
return instance;
}
-(id)copyWithZone:(NSZone *)zone{
return instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
return instance;
}
#pragma mark: 注意和创建的.xcdatamodeld 文件名保持一致
- (NSManagedObjectModel *)objModel{
if (!_objModel) {
// Model 保持和xcdatamodeld 文件名一致,不然modelUrl 为nil
NSURL *modelUrl = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
_objModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
}
return _objModel;
}
#pragma mark: 根据项目情况自己命名要保存的数据库文件名字
- (NSPersistentStoreCoordinator *)persistentCoordinator{
if (!_persistentCoordinator) {
// 创建coordinator
_persistentCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.objModel];
// 指定数据库文件
NSString *urlStr = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"myCoreData.sqlite"];
NSURL *url = [NSURL fileURLWithPath:urlStr];
NSError *error;
[_persistentCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
if (error) {
NSLog(@"创建持久化容器失败 %@",error);
}
}
return _persistentCoordinator;
}
- (NSManagedObjectContext *)context{
if (!_context) {
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_context.persistentStoreCoordinator = self.persistentCoordinator;
}
return _context;
}
#pragma mark : 增删改查方法封装
// 可以根据具体的实体对象进行封装 就不用调用performSelector了
// 添加数据 -- 需要模型名 表名 字典数据 只能通过字典一个一个添加
- (BOOL)insertDataWithEntityName:(NSString *)entityName andDictionary:(NSDictionary *)dict {
// 获取实体对象
NSManagedObject *entity = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.context];
// 遍历参数字典
for (NSString *key in dict) {
// 使用kvc 赋值
// 注意key要和表中字段名保持一致,不区分大小写,但查找不到key值会崩溃
[entity setValue:dict[key] forKey:key];
}
NSError *error;
[self.context save:&error];
if (error) {
NSLog(@"%@",error);
return NO;
}else{
return YES;
}
}
- (BOOL)deleteDataWithEntityName:(NSString *)entityName predicateString:(NSString *)predicateString{
// 获取要删除的记录
NSArray *result = [self selectRecordWithEntityName:entityName andPredicateString:predicateString andSortWithKeyArr:nil andAscending:YES];
for (NSManagedObject *obj in result) {
[self.context deleteObject:obj];
}
NSError *error;
[self.context save:&error];
if (error) {
return NO;
}
return YES;
}
- (BOOL)updateRecordWithEntityName:(NSString *)entityName andPredicateString:(NSString *)predicateString andSetAttributeDict:(NSDictionary*)dict{
NSArray *result = [self selectRecordWithEntityName:entityName andPredicateString:predicateString andSortWithKeyArr:nil andAscending:YES];
for (NSManagedObject *obj in result) {
for (NSString *key in dict) {
// 注意属性名和实体表的字段名要保持一致,不然会崩(但不区分大小写)
// 如果要修改的字段名,表中没有会崩溃
[obj setValue:dict[key] forKey:key];
}
}
NSError *error;
[self.context save:&error];
if (error) {
return NO;
}
return YES;
}
// 返回的数据记得转模型
- (NSArray *)selectRecordWithEntityName:(NSString *)entityName andPredicateString:(NSString *)predicateString andSortWithKeyArr:(NSArray *)sortKeyArr andAscending:(BOOL)ascending{
// 获取实体对象
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// 创建查询条件
if (predicateString != nil) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
// 添加查询条件
request.predicate = predicate;
}
// 设置排序
NSMutableArray *sortDescriptors = [NSMutableArray array];
for (NSString *sortKey in sortKeyArr) {
// 创建排序对象
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending];
// 把排序对象添加到数组中
[sortDescriptors addObject:sortDescriptor];
}
request.sortDescriptors = sortDescriptors;
NSArray *arr = [self.context executeFetchRequest:request error:nil];
return arr;
}
@end
网友评论