【问题标题】:MagicalRecord call multiple save methodsMagicalRecord 调用多个保存方法
【发布时间】:2015-05-27 14:19:48
【问题描述】:

我是 MagicalRecord 的新手。我从不同的方法更新相同的实体时遇到问题。这是我的例子:我有一些从网络服务获得的广告。完成后,如果有任何将它们的活动属性设置为 0,我需要更新数据库中的广告。立即,我需要调用保存我的广告的函数或只更新它们。之后,我需要删除所有过期的广告,然后删除不活动的广告。这些广告实际上是基于语言的,所以每次我更改应用程序的语言时,一些广告就会变得无效。它需要是这样的。这是我的保存和删除代码:

- (void) saveBanners:(NSDictionary *)activeBanner
{
      NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
     [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];

if (activeBanner != nil || [activeBanner count] != 0)
{
    for (int i = 0; i<[activeBanner.banners count]; i++)
    {
        NSDate *dateTo = [formatter dateFromString:[activeBanner.banners[i] DateValidTo]];
        NSDate *dateFrom = [formatter dateFromString:[activeBanner.banners[i] DateValidFrom]];
        NSLog(@"%@ %@", dateTo, [activeBanner.banners[i] DateValidTo]);

        [MagicalRecord
         saveWithBlock:^(NSManagedObjectContext *localContext)
         {
             Banner *banner = [Banner MR_findFirstByAttribute:@"serverId" withValue:[activeBanner.banners[i] ID] inContext:localContext];
             Banner *localBanner;
             if (banner != nil)
             {
                 localBanner = [banner MR_inContext:localContext];
             }
             else
             {
                 localBanner = [Banner MR_createInContext:localContext];
             }

             localBanner.serverId = [activeBanner.banners[i] ID];
             localBanner.name = [activeBanner.banners[i] Name];
             localBanner.text = [activeBanner.banners[i] BannerText];
             localBanner.dateFrom = dateFrom;
             localBanner.dateTo = dateTo;
             localBanner.image = [activeBanner.banners[i] ImageData];
             localBanner.active = [NSNumber numberWithBool:YES];
             localBanner.country = [activeBanner.banners[i] CountryCode];
         }];
    }
}
}

- (void)setBannerInactive:(NSString *)country
{

NSPredicate *bannerFilter = [NSPredicate predicateWithFormat:@"country IN %@", @[[country uppercaseString]]]; // paziti na upperCase, tako vraca u bazi
NSArray *banners = [Banner MR_findAllWithPredicate:bannerFilter];
NSNumber *bannersCount = [Banner MR_numberOfEntitiesWithPredicate:bannerFilter];

if (bannersCount.integerValue != 0)
{
    for (int i = 0; i < bannersCount.integerValue; i++)
    {

        [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
         {
             Banner *banner = [Banner MR_findFirstByAttribute:@"serverId" withValue:[banners[i] serverId] inContext:localContext];

             if (banner != nil)
             {
                 Banner *localBanner = [banner MR_inContext:localContext];
                 localBanner.active = [NSNumber numberWithBool:NO];
             }
         } completion:^(BOOL success, NSError *error) {
             NSLog(@"I am here");
         }];
    }
}
}

- (void)deleteInactiveBanners
{

NSPredicate *inactiveBannerFilter = [NSPredicate predicateWithFormat:@"active = NO"]; // NO = neaktivni
NSArray *banners = [Banner MR_findAllWithPredicate:inactiveBannerFilter];

if (banners != nil || [banners count] != 0)
{
    for (int i = 0; i < [banners count]; i++)
    {
        Banner *banner = banners[i];

        if (banner != nil)
        {
            [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
             {
                 Banner *localBanner = [banner MR_inContext:localContext];
                 [localBanner MR_deleteEntity];
             }];
        }
    }

}
}

我在我的视图控制器中从我的视图模型中调用它们,在我的 RAC 信号的完整块中获取我的广告:

 [self.viewModel setBannerInactive:appLanguage];

     if (self.viewModel.activeBanner != nil)
     {
         [self.viewModel saveBanner:self.splashViewModel.activeBanner];
     }

     [self.viewModel deleteInactiveBanners];

我知道 saveWithBlocks 是在后台线程中执行的。问题是当我调用 setBannerInactive 时,它​​在调用 saveBanners 时并未完成,因此一切都无法正常工作。如何使用 MagicalRecord 正确调用这些方法。我使用的是最新的 2.x MagicalRecord,而不是 v3。?

【问题讨论】:

    标签: ios objective-c core-data magicalrecord


    【解决方案1】:

    类似的东西(我没有尝试也没有尝试编译它,所以它可能包含错误但想法就在那里)

    - (void) saveBanners:(NSDictionary *)activeBanner withCompletion:(void(^)())completionBlock
    {
          NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
         [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
    
    if (activeBanner != nil || [activeBanner count] != 0)
    {
        for (int i = 0; i<[activeBanner.banners count]; i++)
        {
            NSDate *dateTo = [formatter dateFromString:[activeBanner.banners[i] DateValidTo]];
            NSDate *dateFrom = [formatter dateFromString:[activeBanner.banners[i] DateValidFrom]];
            NSLog(@"%@ %@", dateTo, [activeBanner.banners[i] DateValidTo]);
    
            [MagicalRecord
             saveWithBlock:^(NSManagedObjectContext *localContext)
             {
                 Banner *banner = [Banner MR_findFirstByAttribute:@"serverId" withValue:[activeBanner.banners[i] ID] inContext:localContext];
                 Banner *localBanner;
                 if (banner != nil)
                 {
                     localBanner = [banner MR_inContext:localContext];
                 }
                 else
                 {
                     localBanner = [Banner MR_createInContext:localContext];
                 }
    
                 localBanner.serverId = [activeBanner.banners[i] ID];
                 localBanner.name = [activeBanner.banners[i] Name];
                 localBanner.text = [activeBanner.banners[i] BannerText];
                 localBanner.dateFrom = dateFrom;
                 localBanner.dateTo = dateTo;
                 localBanner.image = [activeBanner.banners[i] ImageData];
                 localBanner.active = [NSNumber numberWithBool:YES];
                 localBanner.country = [activeBanner.banners[i] CountryCode];
             } completion:^(BOOL success, NSError *error) {
    if(completionBlock)
    completionBlock();
                 NSLog(@"I am here");
             }];
        }
    }
    }
    
    - (void)setBannerInactive:(NSString *)country withCompletion:(void(^)())completionBlock
    {
    
    NSPredicate *bannerFilter = [NSPredicate predicateWithFormat:@"country IN %@", @[[country uppercaseString]]]; // paziti na upperCase, tako vraca u bazi
    NSArray *banners = [Banner MR_findAllWithPredicate:bannerFilter];
    NSNumber *bannersCount = [Banner MR_numberOfEntitiesWithPredicate:bannerFilter];
    
    if (bannersCount.integerValue != 0)
    {
        for (int i = 0; i < bannersCount.integerValue; i++)
        {
    
            [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
             {
                 Banner *banner = [Banner MR_findFirstByAttribute:@"serverId" withValue:[banners[i] serverId] inContext:localContext];
    
                 if (banner != nil)
                 {
                     Banner *localBanner = [banner MR_inContext:localContext];
                     localBanner.active = [NSNumber numberWithBool:NO];
                 }
             } completion:^(BOOL success, NSError *error) {
                 NSLog(@"I am here");
    if(completionBlock)
    completionBlock();
             }];
        }
    }
    }
    
    - (void)deleteInactiveBanners withCompletion:(void(^)())completionBlock
    {
    
    NSPredicate *inactiveBannerFilter = [NSPredicate predicateWithFormat:@"active = NO"]; // NO = neaktivni
    NSArray *banners = [Banner MR_findAllWithPredicate:inactiveBannerFilter];
    
    if (banners != nil || [banners count] != 0)
    {
        for (int i = 0; i < [banners count]; i++)
        {
            Banner *banner = banners[i];
    
            if (banner != nil)
            {
                [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
                 {
                     Banner *localBanner = [banner MR_inContext:localContext];
                     [localBanner MR_deleteEntity];
                 } completion:^(BOOL success, NSError *error) {
                 NSLog(@"I am here");
    if(completionBlock)
    completionBlock();
             }];
            }
        }
    
    }
    }
    

    这样使用

    [self.viewModel setBannerInactive:appLanguage withCompletion:^(){
    
     if (self.viewModel.activeBanner != nil)
     {
         [self.viewModel saveBanner:self.splashViewModel.activeBanner withCompletion:^(){
             [self.viewModel deleteInactiveBanners withCompletion:nil];
          }];
     }
    else
    {     
         [self.viewModel deleteInactiveBanners withCompletion:nil];
    }
    }];
    

    【讨论】:

    • 你的回答对我有帮助,所以我会支持你
    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多