MagicalRecord的使用

創(chuàng)建數(shù)據(jù)庫

1. 首先分析清楚自己需要什么

我的目的是要緩存信件列表界面妻味,新建列表界面的model就是letter御毅,所以我需要一個Letter的實體(entity)轧抗,那這個Letter有哪些屬性呢?寫信的人(sender)董栽、信的內(nèi)容(content)码倦、信的時間(dateString)、信的已讀未讀狀態(tài)(isRead)锭碳、發(fā)信還是收信(incoming)袁稽;所以我Letter的entity創(chuàng)建之后是這樣:

image1

這樣就好了嗎,并沒有擒抛,如果是普通的展示界面推汽,只有l(wèi)etter的實體,這樣就足夠了歧沪;但是對于我的這個項目來說歹撒,是展示信件的,是比較私人的诊胞,我緩存的信件列表應該只有我能看到暖夭,如果別人在我的手機上登陸了呢?因為我沒有做區(qū)分撵孤,所以迈着,當他登入的時候,他能看到我的數(shù)據(jù)邪码,因為數(shù)據(jù)是緩存在手機上的裕菠!

所以,我需要一個User的Entity闭专,這個User的Entity的目的是:跟Letter綁定奴潘,保證每個人都看到自己應該看到的旧烧;user有兩個attribute:accout和writeName,(正常情況下應該是uid画髓,但是我的這個是比較簡單掘剪,所以沒有uid);

image2

緊接著問題是奈虾,Letter和User之間Relationships杖小,是一對一還是一對多,我的每個letter都應該有一個user愚墓,并且只有一個user,但是我一個user應該有很多l(xiāng)etter昂勉,當我從數(shù)據(jù)庫獲取letter的時候浪册,其實就是拿著user去查找的,當我user跟letter是一對一的話岗照,那我就只能取出一封信村象,明顯是不對的。


image3
image4

結論:我的數(shù)據(jù)庫攒至,有兩個Entity厚者,一個是Letter,一個是User迫吐;Letter和User的Relationships的type是一對一库菲,User和Letter的Relationships的type是一對多;

2. 然后導入MagicalRecord

我之前緩存數(shù)據(jù)一直都是使用的FMDB志膀,沒用過CoreData熙宇,但是當我在拆分成徹底的MVC的時候,我總是希望我可以直接拿著這個model就可以存儲溉浙,取出來就是model烫止,就可以直接使用,而不是一個個屬性戳稽,再重新賦值馆蠕,所以我就想嘗試一下CoreData;但原生的太復雜惊奇,所以就選擇MagicalRecord互躬。

MagicalRecord的使用: github上只有各個方法的使用,但是我沒找到Demo赊时,所以我把我是如何使用的貼出來吨铸,僅供參考

在pch文件里,導入頭文件
a. 在applicationDidFinishLaunchingWithOptions:里初始化

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    
    [MagicalRecord setupAutoMigratingCoreDataStack];    
    // 設置window的rootViewController
    [self setupWindowRootViewController];

    return YES;
}

b. 在程序停止時祖秒,調(diào)用cleanup方法

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    [MagicalRecord cleanUp];
}

c. 生成model類
選中.xcdatamodeld文件诞吱,CMD+N舟奠,

image5

全部勾選,然后生成model類

d. 網(wǎng)絡請求成功后房维,順便保存數(shù)據(jù)

// 將letter保存到數(shù)據(jù)庫
- (void)saveLetterWithLetterEntity:(LetterEntity *)tempLetter {
   // MagicalRecord保存的方法沼瘫,不是主線程
   [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
      // 首先,通過pkNumber查詢咙俩,得到letter
      // 如果letter不存在耿戚,則創(chuàng)建
      // 賦值保存,注意這里的user.lettters是NSSet阿趁,因為
       Letter *letter = [Letter MR_findFirstByAttribute:@"pkNumber" withValue:tempLetter.pkNumber inContext:localContext];
       if (!letter) {
           // 創(chuàng)建letter
           letter = [Letter MR_createEntityInContext:localContext];
           User *user = [User MR_createEntityInContext:localContext];
           letter.user = user;
       }
       letter.dateString = tempLetter.letterDateString;
       letter.content = tempLetter.letterContent;
       letter.sender = tempLetter.letterSender;
       letter.pkNumber = tempLetter.pkNumber;
       letter.incoming = [NSNumber numberWithBool:tempLetter.incoming];
       // 收信默認為未讀膜蛔,發(fā)信默認都是已讀
       if (tempLetter.incoming) {
           // 收信
           letter.isRead = [NSNumber numberWithBool:NO];
       }
       else {
           letter.isRead = [NSNumber numberWithBool:YES];
       }
       
       letter.user.writeName = [[NSUserDefaults standardUserDefaults] objectForKey:k_WRITENAME];
       letter.user.account = [[NSUserDefaults standardUserDefaults] objectForKey:k_USERNAME];
       if (_letters == nil) {
           _letters = [NSMutableArray array];
       }
       [_letters addObject:letter];
       letter.user.letters = [NSSet setWithArray:_letters];
   } completion:^(BOOL contextDidSave, NSError *error) {
       DLog(@"=-===%@", (contextDidSave ? @"saveSuccessed" : @"saveFailure"));
   }];
}

e. 網(wǎng)絡失敗時從數(shù)據(jù)庫獲取數(shù)據(jù)

- (NSMutableArray *)lettersFromDataBase {

    NSMutableArray *receiveArray = [NSMutableArray array];
    NSMutableArray *sendArray = [NSMutableArray array];
    
    NSString *account = [[NSUserDefaults standardUserDefaults] objectForKey:k_USERNAME];
    User *user = [[User MR_findByAttribute:@"account" withValue:account] firstObject];

//    NSPredicate *receivePredicate = [NSPredicate predicateWithFormat:@"incoming == %@ && user == %@", [NSNumber numberWithBool:YES], user];
//    NSPredicate *sendPredicate = [NSPredicate predicateWithFormat:@"incoming == %@ && user == %@", [NSNumber numberWithBool:NO], user];
//    receiveArray = [NSMutableArray arrayWithArray:[Letter MR_findAllWithPredicate:receivePredicate]];
//    sendArray = [NSMutableArray arrayWithArray:[Letter MR_findAllWithPredicate:sendPredicate]];

    
    NSArray *userLetters = [Letter MR_findByAttribute:@"user" withValue:user];
    if (userLetters) {
        for (int i = 0; i < userLetters.count; i++) {
            Letter *tempLetter = userLetters[i];
            LetterEntity *tempEntity = [[LetterEntity alloc] init];
            tempEntity.letterContent = tempLetter.content;
            tempEntity.letterDateString = tempLetter.dateString;
            tempEntity.letterSender = tempLetter.sender;
            tempEntity.pkNumber = tempLetter.pkNumber;
            tempEntity.incoming = [tempLetter.incoming boolValue];

            if ([tempLetter.incoming boolValue]) {
                [receiveArray addObject:tempEntity];
            }
            else {
                [sendArray addObject:tempEntity];
            }
        }
    }
    // 這里的順序不能錯,sendArray在前脖阵,receiveArray在后面
    NSMutableArray *resultArray = [NSMutableArray arrayWithObjects: sendArray, receiveArray, nil];
    return resultArray;
}

參考

  1. 深入淺出MagicalRecord皂股,這篇博客講的很詳細,從CoreData到MagicalRecord

  2. RayWenderlich的MagicalRecord Tutorial命黔,這篇是教程呜呐,可以跟著敲,練習

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悍募,一起剝皮案震驚了整個濱河市蘑辑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坠宴,老刑警劉巖洋魂,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異喜鼓,居然都是意外死亡忧设,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門颠通,熙熙樓的掌柜王于貴愁眉苦臉地迎上來址晕,“玉大人,你說我怎么就攤上這事顿锰〗骼” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵硼控,是天一觀的道長刘陶。 經(jīng)常有香客問我,道長牢撼,這世上最難降的妖魔是什么匙隔? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮熏版,結果婚禮上纷责,老公的妹妹穿的比我還像新娘捍掺。我一直安慰自己,他們只是感情好再膳,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布挺勿。 她就那樣靜靜地躺著,像睡著了一般喂柒。 火紅的嫁衣襯著肌膚如雪不瓶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天灾杰,我揣著相機與錄音蚊丐,去河邊找鬼。 笑死艳吠,一個胖子當著我的面吹牛吠撮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讲竿,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弄屡!你這毒婦竟也來了题禀?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤膀捷,失蹤者是張志新(化名)和其女友劉穎迈嘹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體全庸,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡秀仲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壶笼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片神僵。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖覆劈,靈堂內(nèi)的尸體忽然破棺而出保礼,到底是詐尸還是另有隱情,我是刑警寧澤责语,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布炮障,位于F島的核電站,受9級特大地震影響坤候,放射性物質發(fā)生泄漏胁赢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一白筹、第九天 我趴在偏房一處隱蔽的房頂上張望智末。 院中可真熱鬧谅摄,春花似錦、人聲如沸吹害。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽它呀。三九已至螺男,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纵穿,已是汗流浹背下隧。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谓媒,地道東北人淆院。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像句惯,于是被迫代替她去往敵國和親土辩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容