你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS CoreData引見和運用(以及一些留意事項)

iOS CoreData引見和運用(以及一些留意事項)

編輯:IOS開發綜合

IOS CoreData引見和運用(以及一些留意事項)

最近花了一點時間整理了一下CoreData,關於常常運用SQLite的我來說,用這個真的有點用不慣,團體覺得真實是沒發現什麼亮點,不喜勿噴啊。不過這門技術的呈現也有其存在價值,這是不可否認的現實,即便是不喜歡我們也得去理解一下,由於你不必他人會用,這年頭都多人開發,多學點還是有益處的。廢話不多說了,該開端正派事了。

CoreData引見

CoreData是一個模型層的技術,也是一種耐久化技術(數據庫),它能將模型對象的形態耐久化到磁盤裡,我們不需求運用SQL語句就能對它停止操作。不過在功能方面是弱於直接運用SQLite的。

CoreData運用

實際我就不多說了,覺得我說的不夠詳細的可以自行搜索關於更多的CoreData引見。

創立步驟流程 第一步先創立.xcdatamodeld文件(New File -> IOS -> Core Data ->Data Model) IOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-07 下午10.40.16.png

名字雖然可以恣意取,但最好還是取和自己存儲數據庫名字一樣的名字。這樣可讀性更高些。(ps:這個文件就相當於數據庫文件一樣,數據庫文件中可以有多個表,表中可以有各個字段值,這裡也可以有多個實體,每個實體有各個鍵值)

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-07 下午10.40.40.png

經過下面的操作就可以創立一個.xcdatamodeld文件,如今我們點擊這個文件,在最上面找到Add Entity按鈕,停止實體添加。

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午8.50.10.png

如今我們添加了一個名字為Entity的實體,這個名字是默許名字,如今我們可以對他停止名字的更改,對它雙擊一下即可修正名字,或許在xcode左邊的信息欄中也可以修正

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午9.09.38.png

經過下面操作我們曾經創立好了實體的名字,如今我們需求往實體中添加我們需求的鍵值。(ps:相當於數據庫表中的字段),詳細操作看圖說話(實體之間的關聯我就不引見了,有興味的可以自行搜索材料,團體覺得會了單個實體創立外加查詢就行,關聯也無非是找到關聯的實體中共同的鍵值從而獲得另外一個實體對象,我們可以直接先從一個實體獲得指定鍵值對應的屬性,再經過屬性值去查詢另一個實體,只是沒關聯的那麼方便而已)。

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午9.17.43.png

第二步創立關聯類來操控CoreData實體對象(選中.xcdatamodeld文件->xcode菜單欄->Edit->Create NSManagedObject Subclass) iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午9.35.57.png

選中自己需求關聯的.xcdatamodeld文件稱號,點擊下一步即可。

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午9.47.24.png

選中.xcdatamodeld文件中需求關聯的實體對象,點擊下一步然後在選擇存儲目錄即可。

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午9.48.06.png

完成後會發現自動生成了實體稱號對應的類和擴展類(Entity.h/.m和Entity+CoreDataProperties.h/.m)

iOS CoreData介紹和使用(以及一些注意事項)
屏幕快照 2016-07-13 下午10.23.22.png

到這裡就完成了整一個創立的流程,團體覺得說的有點過於詳細了(招致看起來有點啰嗦)

留意
我在實驗的進程中發現,假如我把關聯的類從項目中刪除,在對實體稱號再次修正後,重新創立關聯類,發現類名還是原來的實體稱號顯示,能夠xcode沒刷新,反正最後我是刪除實體重新Add Entity之後才有用,所以為了不用要費事,最好還是想好實體稱號後再創立關聯類。

關聯類的了解

我就以我自己創立的類來闡明

#import "UploadEntity.h"

NS_ASSUME_NONNULL_BEGIN

@interface UploadEntity (CoreDataProperties)

@property (nullable, nonatomic, retain) NSString *fileName;
@property (nullable, nonatomic, retain) NSString *fileSize;
@property (nullable, nonatomic, retain) NSNumber *fileType;
@property (nullable, nonatomic, retain) NSNumber *finishStatus;
@property (nullable, nonatomic, retain) NSData *imageData;
@property (nullable, nonatomic, retain) NSNumber *time;
@property (nullable, nonatomic, retain) NSString *urlPath;

@end

NS_ASSUME_NONNULL_END

該類承繼NSManagedObject類

可以看到在實體中的每一個鍵值都被xcode自動生成了實體類的對象屬性,而且關於根本數據類型被自動轉成了NSNumber。

每個對象的修飾詞都有nullable,表示CoreData數據庫存儲的對象能夠為nil(允許存儲nil,就如數據庫一樣,字段值也能為NULL),也就是說我們當前從CoreData讀取的數據是有能夠為nil。

這個類對象的創立我們不能用以往的[[NSObject alloc] init]方式去創立,由於經過驗證直接這樣創立它,然後對屬性賦值會直接拋出異常,估量外部經行了斷言操作吧。蘋果API提供了幾個專門創立實體對象的辦法,前面我在講。

由於各種限制的緣由,比方創立對象限制等,招致了我不好去封裝,最後不得已想到個折中方法(上面會講)。根本這一輪上去我的興味缺失了很多。

CoreData API引見

NSManagedObjectContext

 這個對象有點像SQLite對象(團體了解:用來管理.xcdatamodeld中的數據)。
 擔任數據和使用庫之間的交互(CRUD,即增刪改查、保管等接口都是用這個對象調用).
 每個 NSManagedObjectContext 和其他 NSManagedObjectContext 都是完全獨立的。
 一切的NSManagedObject(團體了解:實體數據)都存在於NSManagedObjectContext中。
 每個NSManagedObjectContext都知道自己管理著哪些NSManagedObject(團體了解:實體數據)
 // 創立方式(普通這個對象最好聲明成成員變量)
 self.context = [[NSManagedObjectContext alloc] init];
 // 保管信息(比擬重要的操作,每次更新和拔出以及刪除後必需做的操作)
 NSError *error = nil;
 BOOL result = [self.context save:&error];
 if (!result) {
    NSLog(@"添加數據失敗:%@",error);
    if (fail) {
        fail(error);
    }
 } else {
    NSLog(@"添加數據成功");
    if (success) {
        success();
    }
 }
NSManagedObjectModel
Core Data的模型文件,有點像SQLite的.sqlite文件(團體了解:表示一個.xcdatamodeld文件)
// 創立方式
// 1.自動加載指定稱號的.xcdatamodeld資源
//獲取模型途徑
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelName
                                            withExtension:@"momd"];
//依據模型文件創立模型對象
NSManagedObjectModel *model = [[NSManagedObjectModel alloc]
                                    initWithContentsOfURL:modelURL];
 // 2.從使用順序包中加載.xcdatamodeld模型文件                              
 NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];

NSPersistentStoreCoordinator

耐久化存儲庫,CoreData的存儲類型(比方SQLite數據庫就是其中一種)。
用來將對象管理局部和耐久化局部捆綁在一同,擔任互相之間的交流(中介一樣)
用來設置CoreData存儲類型和存儲途徑
對象和數據庫之間的交互不需求我們來關懷,蘋果幫我們做好了。我們只需求面向OC開發
// 創立方式
/**
  留意:創立NSPersistentStoreCoordinator前必需創立NSManagedObjectModel
        團體了解:好比在一個數據庫中創立表前需求設置表的一切字段,
                這裡傳入NSManagedObjectModel模型(.xcdatamodeld模型文件),
                覺得就是讓CoreData知道一切模型中的實體中的一切鍵值,
                從而好創立CoreData數據庫              
*/ 
// 以傳入NSManagedObjectModel模型方式初始化耐久化存儲庫
NSPersistentStoreCoordinator *persistent = [[NSPersistentStoreCoordinator alloc]
                                              initWithManagedObjectModel:model];
/*
   耐久化存儲庫的類型:
   NSSQLiteStoreType  SQLite數據庫
   NSBinaryStoreType  二進制立體文件
   NSInMemoryStoreType 內存庫,無法永世保管數據
   雖然這3品種型的功能從速度下去說都差不多,但從數據模型中保存上去的信息卻不一樣
   在簡直一切的情形中,都應該采用默許設置,運用SQLite作為耐久化存儲庫
 */
// 添加一個耐久化存儲庫並設置類型和途徑,NSSQLiteStoreType:SQLite作為存儲庫
NSError *error = nil;
// 名字最好和.xcdatamodeld文件的名字一樣
NSString *sqlPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                        NSUserDomainMask, YES) 
                                                                   lastObject] 
                                  stringByAppendingPathComponent:@"xxx.sqlite"];
[persistent addPersistentStoreWithType:NSSQLiteStoreType configuration:nil 
                                        URL:[NSURL fileURLWithPath:sqlPath]
                                        options:nil 
                                        error:&error];
if (error) {
    NSLog(@"添加數據庫失敗:%@",error);
    if (fail) {
        fail(error);
    }
} else {
     NSLog(@"添加數據庫成功");
    // 設置上下文所要關聯的耐久化存儲庫(這一步千萬不要遺忘)
    self.context.persistentStoreCoordinator = self.persistent;
    if (success) {
        success();
    }
}
NSEntityDescription
用來描繪實體(Entity):相當於數據庫表中一組數據描繪(純屬團體了解)
經過Core Data從數據庫中取出的對象,默許狀況下都是NSManagedObject對象.
 NSManagedObject的任務形式有點類似於NSDictionary對象,經過鍵-值對來存取一切的實體屬性.
 setValue:forkey:存儲屬性值(屬性名為key);
 valueForKey:獲取屬性值(屬性名為key).
 每個NSManagedObject都知道自己屬於哪個NSManagedObjectContext
// 創立方式(用於拔出數據運用:取得實體,改動實體各個屬性值,保管後就代表拔出)
/**
  留意:不能用 alloc init方式創立
  經過傳入上下文和實體稱號,創立一個稱號對應的實體對象
  (相當於數據庫一組數據,其中含有多個字段)
  團體覺得有種先拔出一個新的Entity從而取得Entity,在停止各屬性賦值
*/
NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:
                                                                  entityName 
                                              inManagedObjectContext:self.context];

CoreData的增刪改查

下面說了這麼多一直沒描繪如何去操作它,如今先說說大約步驟。

insert
1.依據Entity稱號和NSManagedObjectContext獲取一個新的NSManagedObject
  NSManagedObject *newEntity = [NSEntityDescription
                                insertNewObjectForEntityForName:entityName 
                                inManagedObjectContext:self.context];
2.依據Entity中的鍵值,逐個對應經過setValue:forkey:給NSManagedObject對象賦值
  [newEntity setValue:value forKey:key];
3.保管修正
  NSError *error = nil;
  BOOL result = [self.context save:&error];
delete
1.經過查詢(設置好查詢條件)懇求獲得需求刪除的NSManagedObject的一切集合
2.經過for循環調用deleteObject:辦法停止逐一刪除(團體疑心這個for循環會不會招致功能問題),
  暫時沒發現其它刪除辦法。
  [self.context deleteObject:entity];
3.保管修正
update
1.經過查詢(設置好查詢條件)懇求獲得需求修正的NSManagedObject的一切集合
2.經過for循環調用NSManagedObject對象的setValue:forkey:辦法給各個屬性賦值
3.保管修正
read
1.創立NSFetchRequest查詢懇求對象
  NSFetchRequest *request = [[NSFetchRequest alloc] init];
2.設置需求查詢的實體描繪NSEntityDescription
  NSEntityDescription *desc = [NSEntityDescription entityForName:self.entityName
                                            inManagedObjectContext:self.context];
  request.entity = desc;
3.設置排序順序NSSortDescriptor對象集合(可選)
  request.sortDescriptors = descriptorArray;
4.設置條件過濾(可選)
  NSPredicate *predicate = [NSPredicate predicateWithFormat:filterStr];
  request.predicate = predicate;
5.執行查詢懇求
  NSError *error = nil;
  // NSManagedObject對象集合
  NSArray *objs = [self.context executeFetchRequest:request error:&error];
  // 查詢後果數目
  NSUInteger count = [self.context countForFetchRequest:request error:&error];

從下面可以看出假如我們僅僅是復雜的對CoreData停止增刪改查的操作的話,略微費點心思的就屬查詢這一塊。外面觸及到了兩個對象NSSortDescriptor和NSPredicate,辨別用於設置排序和過濾查詢條件的,尤其是NSPredicate,它不只僅用於CoreData,還被常常用於數組的過濾。詳細對這兩個對象的引見我就不說了,覺得這一篇寫多了。上面我直接上代碼。不在多講了。

CoreData團體小封裝

下面提到實體的創立要素招致了封裝重用的難度,根本上新建一個.xcdatamodeld文件就得做好特意為它寫一些操作接口的預備。

CoreDataAPI.h/.m

//
//  CoreDataAPI.h
//  TedcallStorage
//
//  Created by  tedcall on 16/7/1.
//  Copyright © 2016年 pocket. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CoreDataAPI : NSObject
/**
 *  獲取數據庫存儲的途徑
 */
@property (nonatomic,copy,readonly) NSString *sqlPath;
/**
 *  獲取.xcdatamodeld文件的稱號
 */
@property (nonatomic,copy,readonly) NSString *modelName;
/**
 *  獲取.xcdatamodeld文件中創立的實體的稱號
 */
@property (nonatomic,copy,readonly) NSString *entityName;

/**
 *  創立CoreData數據庫
 *
 *  @param entityName 實體稱號
 *  @param modelName  .xcdatamodeld文件稱號(為nil則自動從順序包加載模型文件)
 *  @param sqlPath    數據庫存儲的途徑
 *  @param success    成功回調
 *  @param fail       失敗回調
 *
 *  @return 前往CoreDataAPI對象
 */
- (instancetype)initWithCoreData:(NSString *)entityName modelName:(NSString *)modelName sqlPath:(NSString *)sqlPath success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  拔出數據
 *
 *  @param dict 字典中的鍵值對必需要與實體中的每個名字逐個對應
 *  @param success    成功回調
 *  @param fail       失敗回調
 */
- (void)insertNewEntity:(NSDictionary *)dict success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  查詢數據
 *
 *  @param sequenceKeys 數組初級排序(數組裡寄存實體中的key,順序按自己需求的先後寄存即可),實體key來排序
 *  @param isAscending  能否上升排序
 *  @param filterStr    過濾語句
 *  @param success      成功後後果回調
 *  @param fail         失敗回調
 */
- (void)readEntity:(NSArray *)sequenceKeys ascending:(BOOL)isAscending filterStr:(NSString *)filterStr success:(void(^)(NSArray *results))success fail:(void(^)(NSError *error))fail;

/**
 *  刪除數據
 *
 *  @param entity  NSManagedObject
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)deleteEntity:(NSManagedObject *)entity success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  更新數據
 *
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)updateEntity:(void(^)(void))success fail:(void(^)(NSError *error))fail;
@end
//
//  CoreDataAPI.m
//  TedcallStorage
//
//  Created by  tedcall on 16/7/1.
//  Copyright © 2016年 pocket. All rights reserved.
//

/**
 *  知識點:
 NSManagedObject:
     經過Core Data從數據庫中取出的對象,默許狀況下都是NSManagedObject對象.
     NSManagedObject的任務形式有點類似於NSDictionary對象,經過鍵-值對來存取一切的實體屬性.
     setValue:forkey:存儲屬性值(屬性名為key);
     valueForKey:獲取屬性值(屬性名為key).
     每個NSManagedObject都知道自己屬於哪個NSManagedObjectContext

 NSManagedObjectContext:
    擔任數據和使用庫之間的交互(CRUD,即增刪改查、保管等接口都在這個對象中).
    一切的NSManagedObject都存在於NSManagedObjectContext中,所以對象和context是相關聯的
    每個 context 和其他 context 都是完全獨立的
    每個NSManagedObjectContext都知道自己管理著哪些NSManagedObject

 NSPersistentStoreCoordinator:
    添加耐久化存儲庫,CoreData的存儲類型(比方SQLite數據庫就是其中一種)
    兩頭審查者,用來將對象圖管理局部和耐久化局部捆綁在一同,擔任互相之間的交流(中介一樣)

 NSManagedObjectModel:
    Core Data的模型文件

 NSEntityDescription:
    用來描繪實體:相當於數據庫表中一組數據描繪
 */

#import "CoreDataAPI.h"
#import <CoreData/CoreData.h>
@interface CoreDataAPI()
/**
 *  數據模型對象
 */
@property (nonatomic,strong) NSManagedObjectModel *model;
/**
 *  上下文
 */
@property (nonatomic,strong) NSManagedObjectContext *context;
/**
 *  耐久性存儲區
 */
@property (nonatomic,strong) NSPersistentStoreCoordinator *persistent;
@end

@implementation CoreDataAPI

- (instancetype)initWithCoreData:(NSString *)entityName modelName:(NSString *)modelName sqlPath:(NSString *)sqlPath success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    if (self = [super init]) {
        // 斷言(實體稱號和存儲途徑能否為nil)
        // ...

        _entityName = entityName;
        _modelName = modelName;
        _sqlPath = sqlPath;
        // 初始化上下文
        self.context = [[NSManagedObjectContext alloc] init];
        if (modelName) {
            //獲取模型途徑
            NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelName withExtension:@"momd"];
            //依據模型文件創立模型對象
            self.model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        } else { // 從使用順序包中加載模型文件
            self.model = [NSManagedObjectModel mergedModelFromBundles:nil];
        }

        // 以傳入模型方式初始化耐久化存儲庫
        self.persistent = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
        /*
         耐久化存儲庫的類型:
         NSSQLiteStoreType  SQLite數據庫
         NSBinaryStoreType  二進制立體文件
         NSInMemoryStoreType 內存庫,無法永世保管數據
         雖然這3品種型的功能從速度下去說都差不多,但從數據模型中保存上去的信息卻不一樣
         在簡直一切的情形中,都應該采用默許設置,運用SQLite作為耐久化存儲庫
         */
        // 添加一個耐久化存儲庫並設置類型和途徑,NSSQLiteStoreType:SQLite作為存儲庫
        NSError *error = nil;
        [self.persistent addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlPath] options:nil error:&error];
        if (error) {
            NSLog(@"添加數據庫失敗:%@",error);
            if (fail) {
                fail(error);
            }
        } else {
             NSLog(@"添加數據庫成功");
            // 設置上下文所要關聯的耐久化存儲庫
            self.context.persistentStoreCoordinator = self.persistent;
            if (success) {
                success();
            }
        }
    }

    return self;
}

// 添加數據
- (void)insertNewEntity:(NSDictionary *)dict success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    if (!dict||dict.allKeys.count == 0) return;
    // 經過傳入上下文和實體稱號,創立一個稱號對應的實體對象(相當於數據庫一組數據,其中含有多個字段)
    NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:self.entityName inManagedObjectContext:self.context];
    // 實體對象存儲屬性值(相當於數據庫中將一個值存入對應字段)
    for (NSString *key in [dict allKeys]) {
        [newEntity setValue:[dict objectForKey:key] forKey:key];
    }
    // 保管信息,同步數據
    NSError *error = nil;
    BOOL result = [self.context save:&error];
    if (!result) {
        NSLog(@"添加數據失敗:%@",error);
        if (fail) {
            fail(error);
        }
    } else {
        NSLog(@"添加數據成功");
        if (success) {
            success();
        }
    }
}

// 查詢數據
- (void)readEntity:(NSArray *)sequenceKeys ascending:(BOOL)isAscending filterStr:(NSString *)filterStr success:(void(^)(NSArray *results))success fail:(void(^)(NSError *error))fail
{
    // 1.初始化一個查詢懇求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // 2.設置要查詢的實體
    NSEntityDescription *desc = [NSEntityDescription entityForName:self.entityName inManagedObjectContext:self.context];
    request.entity = desc;
    // 3.設置查詢後果排序
    if (sequenceKeys&&sequenceKeys.count>0) { // 假如停止了設置排序
        NSMutableArray *array = [NSMutableArray array];
        for (NSString *key in sequenceKeys) {
            /**
             *  設置查詢後果排序
             *  sequenceKey:依據某個屬性(相當於數據庫某個字段)來排序
             *  isAscending:能否升序
             */
            NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:key ascending:isAscending];
            [array addObject:sort];
        }
        if (array.count>0) {
            request.sortDescriptors = array;// 可以添加多個排序描繪器,然後按順序放進數組即可
        }
    }
    // 4.設置條件過濾
    if (filterStr) { // 假如設置了過濾語句
        NSPredicate *predicate = [NSPredicate predicateWithFormat:filterStr];
        request.predicate = predicate;
    }
    // 5.執行懇求
    NSError *error = nil;
    NSArray *objs = [self.context executeFetchRequest:request error:&error]; // 取得查詢數據數據集合
    if (error) {
        if (fail) {
            fail(error);
        }
    } else{
        if (success) {
            success(objs);
        }
    }
}

// 更新數據
- (void)updateEntity:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    NSError *error = nil;
    [self.context save:&error];
    if (error) {
        NSLog(@"刪除失敗:%@",error);
        if (fail) {
            fail(error);
        }
    } else {
        if (success) {
            success();
        }
    }

}

// 刪除數據
- (void)deleteEntity:(NSManagedObject *)entity success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    // 傳入需求刪除的實體對象
    [self.context deleteObject:entity];
    // 同步到數據庫
    NSError *error = nil;
    [self.context save:&error];
    if (error) {
        NSLog(@"刪除失敗:%@",error);
        if (fail) {
            fail(error);
        }
    } else {
        if (success) {
            success();
        }
    }
}
@end

用法(UploadCoreDataAPI.h/.m)

//
//  UploadCoreDataAPI.h
//  TedcallStorage
//
//  Created by  tedcall on 16/7/14.
//  Copyright © 2016年 pocket. All rights reserved.
//

#import <Foundation/Foundation.h>
@class ResourceModel,DownLoadModel;
@interface UploadCoreDataAPI : NSObject
/**
 *  上傳數據庫模型稱號
 */
@property (nonatomic,copy,readonly) NSString *coreDataModelName;
/**
 *  上傳數據庫實體稱號
 */
@property (nonatomic,copy,readonly) NSString *coreDataEntityName;
/**
 *  上傳數據庫存儲途徑
 */
@property (nonatomic,copy,readonly) NSString *coreDataSqlPath;
+ (instancetype)sharedInstance;
/**
 *  拔出上傳記載
 *
 *  @param model   數據模型
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)insertUploadModel:(ResourceModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  更新上傳記載
 *
 *  @param model   數據模型
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)updateUploadModel:(DownLoadModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  刪除一條上傳記載
 *
 *  @param model   數據模型
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)deleteUploadModel:(DownLoadModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  刪除一切上傳記載
 *
 *  @param success 成功回調
 *  @param fail    失敗回調
 */
- (void)deleteAllUploadModel:(void(^)(void))success fail:(void(^)(NSError *error))fail;

/**
 *  查詢上傳數據庫一切數據
 *
 *  @param success 成功回調(finishArray:已完成(DownLoadModel對象數組) unfinishedArray:未完成(DownLoadModel對象數組))
 *  @param fail    失敗回調
 */
- (void)readAllUploadModel:(void(^)(NSArray *finishArray,NSArray *unfinishedArray))success fail:(void(^)(NSError *error))fail;
@end
//
//  UploadCoreDataAPI.m
//  TedcallStorage
//
//  Created by  tedcall on 16/7/14.
//  Copyright © 2016年 pocket. All rights reserved.
//

#import "UploadCoreDataAPI.h"
#import "CoreDataAPI.h"
#import "ResourceModel.h"
#import "DownLoadModel.h"
static NSString * const modelName = @"Upload";
static NSString * const entityName = @"UploadEntity";
static NSString * const sqliteName = @"Upload.sqlite";
@interface UploadCoreDataAPI()
@property (nonatomic,strong) CoreDataAPI *uploadData;
@end
@implementation UploadCoreDataAPI
static UploadCoreDataAPI *uploadCoreData = nil;
+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        uploadCoreData = [[UploadCoreDataAPI alloc] init];
    });

    return uploadCoreData;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (uploadCoreData == nil) {
            uploadCoreData = [super allocWithZone:zone];
        }
    });

    return uploadCoreData;
}

- (instancetype)init
{
    if (self = [super init]) {
        [self initUploadCoreData];
    }
    return self;
}

- (void)initUploadCoreData
{
    _coreDataEntityName = entityName;
    _coreDataModelName = modelName;
    _coreDataSqlPath = [[[FileManager shardInstance] getDocumentPath] stringByAppendingPathComponent:sqliteName];
    self.uploadData = [[CoreDataAPI alloc] initWithCoreData:self.coreDataEntityName modelName:self.coreDataModelName sqlPath:self.coreDataSqlPath success:^{
        NSLog(@"initUploadCoreData success");
    } fail:^(NSError *error) {
        NSLog(@"initUploadCoreData fail");
    }];

}

#pragma mark - -- 拔出上傳記載
- (void)insertUploadModel:(ResourceModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    NSString *fileName = model.fileName;
    NSString *fileSize = [NSString stringWithFormat:@"%.2lf",model.size];
    NSString *urlPath = model.path;
    NSNumber *time = [NSNumber numberWithInt:[[DateManager sharedInstance] getSecondsSince1970]];
    NSNumber *fileType = [NSNumber numberWithInt:model.fileType];
    NSNumber *finishStatus = [NSNumber numberWithBool:NO];
    NSDictionary *dict = NSDictionaryOfVariableBindings(fileName,fileSize,urlPath,time,fileType,finishStatus);

    [self.uploadData insertNewEntity:dict success:^{
        if (success) {
            success();
        }
    } fail:^(NSError *error) {
        if (fail) {
            fail(error);
        }
    }];
}

#pragma mark - -- 更新上傳記載
- (void)updateUploadModel:(DownLoadModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    NSString *filterStr = [NSString stringWithFormat:@"time = %d AND urlPath = '%@' AND fileName = '%@'",model.time,model.urlPath,model.fileName];
    [self.uploadData readEntity:nil ascending:YES filterStr:filterStr success:^(NSArray *results) {
        if (results.count>0) {
            NSManagedObject *obj = [results firstObject];
            [obj setValue:[NSNumber numberWithBool:model.finishStatus] forKey:@"finishStatus"];
            [self.uploadData updateEntity:^{
                if (success) {
                    success();
                }
            } fail:^(NSError *error) {
                if (fail) {
                    fail(error);
                }
            }];
        }
    } fail:^(NSError *error) {
        if (fail) {
            fail(error);
        }
    }];
}

#pragma mark - -- 刪除一條上傳記載
- (void)deleteUploadModel:(DownLoadModel *)model success:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    NSString *filterStr = [NSString stringWithFormat:@"time = %d AND urlPath = '%@' AND fileName = '%@'",model.time,model.urlPath,model.fileName];
    [self.uploadData readEntity:nil ascending:YES filterStr:filterStr success:^(NSArray *results) {
        if (results.count>0) {
            NSManagedObject *obj = [results firstObject];
            [self.uploadData deleteEntity:obj success:^{
                if (success) {
                    success();
                }
            } fail:^(NSError *error) {
                if (fail) {
                    fail(error);
                }
            }];
        }
    } fail:^(NSError *error) {
        if (fail) {
            fail(error);
        }
    }];
}

#pragma mark - -- 刪除一切上傳記載
- (void)deleteAllUploadModel:(void(^)(void))success fail:(void(^)(NSError *error))fail
{
    [self.uploadData readEntity:nil ascending:YES filterStr:nil success:^(NSArray *results) {
        for (NSManagedObject *obj in results){
            [self.uploadData deleteEntity:obj success:^{
                if (success) {
                    success();
                }
            } fail:^(NSError *error) {
                if (fail) {
                    fail(error);
                }
            }];
        }
    } fail:^(NSError *error) {
        if (fail) {
            fail(error);
        }
    }];
}

#pragma mark - -- 查詢一切上傳記載
- (void)readAllUploadModel:(void(^)(NSArray *finishArray,NSArray *unfinishedArray))success fail:(void(^)(NSError *error))fail
{
    [self.uploadData readEntity:nil ascending:YES filterStr:nil success:^(NSArray *results) {
        NSMutableArray *finishArray = [NSMutableArray array];
        NSMutableArray *unfinishedArray = [NSMutableArray array];
        for (NSManagedObject *obj in results) {
            DownLoadModel *model = [[DownLoadModel alloc] init];
            // 獲取數據庫中各個鍵值的值
            model.fileName = [obj valueForKey:@"fileName"];
            model.fileSize = [obj valueForKey:@"fileSize"];
            model.urlPath = [obj valueForKey:@"urlPath"];
            model.time = [[obj valueForKey:@"time"] intValue];
            model.fileType = [[obj valueForKey:@"fileType"] intValue];
            model.imageData = [obj valueForKey:@"imageData"];
            model.finishStatus = [[obj valueForKey:@"finishStatus"] intValue];
            if (model.finishStatus) {
                [finishArray addObject:model];
            } else {
                [unfinishedArray addObject:model];
            }

        }
        if (success) {
            success(finishArray,unfinishedArray);
        }
    } fail:^(NSError *error) {
        if (fail) {
            fail(error);
        }
    }];
}
@end

【iOS CoreData引見和運用(以及一些留意事項)】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved