【问题标题】:Core data objects should automatically be sorted at midnight核心数据对象应在午夜自动排序
【发布时间】:2014-02-17 19:39:09
【问题描述】:

我正在为 iOS 创建一个待办事项列表应用程序。待办事项列表分为几个部分:

第 0 部分 -> 过期项目

第 1 节 -> 今日项目

第 2 部分 -> 明天的项目

第 3 部分 -> 即将推出的项目

第 4 节 -> 某天项目

第 5 部分 -> 已完成的项目

正如您想象的那样,午夜过后,剩余的 TODAY 项目应该传递到 OVERDUE 部分,TOMORROW 项目应该传递到 TODAY 部分,而一些 UPCOMING 项目应该传递到 TOMORROW 部分。

应用程序现在的样子,如果用户在早上启动应用程序,所有项目都会显示在各自的部分中。

当用户在午夜之前使用应用程序并且刚刚过了午夜时,就会出现此问题。这些项目不会自动传递到正确的部分。

我只能在模拟器上测试应用,但我猜这个问题也会在真机上发生。

所有项目都有一个名为 todoDueDate 的属性,并且所有项目的日期值都具有相同的时间部分,所有项目的时间都设置为上午 10:00。

为了将项目分配到部分中,我使用了一个名为 sectionIdentifier 的临时属性,该属性在名为 ToDoItem 的 NSManagedObject 子类中定义。

这里有方法:

-(NSString *)sectionIdentifier{

    [self willAccessValueForKey:@"sectionIdentifier"];
    NSString *tmp = [self primitiveValueForKey:@"sectionIdentifier"];
    [self didAccessValueForKey:@"sectionIdentifier"];




    if (!tmp){


        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);

        NSDate *today = [NSDate date];
        NSDate *date = self.todoDueDate;

        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setCalendar:calendar];
        [components setYear:2065];
        [components setMonth:11];
        [components setDay:12];

        NSDate *dateFuturoSomeday = [calendar dateFromComponents:components];

        NSCalendar *calendar1 = [NSCalendar currentCalendar];
        NSDateComponents *components1 = [[NSDateComponents alloc] init];
        [components1 setCalendar:calendar1];
        [components1 setYear:2065];
        [components1 setMonth:11];
        [components1 setDay:13];

        NSDate *dateFuturoCompleted = [calendar1 dateFromComponents:components1];




        NSDateComponents *date1Components = [calendar components:comps
                                                        fromDate: today];
        NSDateComponents *date2Components = [calendar components:comps
                                                        fromDate: date];
        NSDateComponents *date3Components = [calendar components:comps
                                                        fromDate: dateFuturoSomeday];
        NSDateComponents *date4Components = [calendar components:comps
                                                        fromDate: dateFuturoCompleted];


        today = [calendar dateFromComponents:date1Components];
        date = [calendar dateFromComponents:date2Components];
        dateFuturoSomeday = [calendar dateFromComponents:date3Components];
        dateFuturoCompleted = [calendar dateFromComponents:date4Components];



        NSInteger daysAfterToday = [calendar components:NSDayCalendarUnit
                                               fromDate:today toDate:date options:0].day;
       // NSString *section;
        if (daysAfterToday < 0) {
            tmp  = @"0";
        } else if (daysAfterToday == 0) {
            tmp = @"1";
        } else if (daysAfterToday > 0 && daysAfterToday < 2) {
            tmp = @"2";
        }
        else if ([self.todoDueDate isEqualToDate:dateFuturoSomeday]){
            tmp = @"4";
        }
        else if ([self.todoDueDate isEqualToDate:dateFuturoCompleted]){
            tmp = @"5";
        }
        else {
            tmp = @"3";
        }






        [self setPrimitiveValue:tmp forKey:@"sectionIdentifier"];

    }


    return tmp;

}

我可以做些什么来实现所需的行为?这意味着,当用户在午夜使用应用程序时,项目应自动传递到预期部分。

谢谢。

【问题讨论】:

    标签: ios core-data nsdate


    【解决方案1】:

    结帐UILocalNotification。

    虽然设计用于......嗯,本地通知,但您可以轻松地使用通知触发作为刷新获取数据排序的方法。

    建议:

    • applicationDidBecomeActive - 安排当晚午夜的 UILocaleNotification(可选择将其设置为每天重复...以防有人将其打开超过 24 小时!)
    • applicationDidEnterBackground - 取消通知
    • 为了处理通知,this post(虽然老了)对如何设置 UILocationNotification 并处理它从应用程序委托触发有一个不错的概述。在您的情况下,只需强制更新排序即可。

    【讨论】:

    • 谢谢@greymouser,我会尝试这样做。但是我需要注意时区吗?
    • @mvasco 我几乎可以肯定地假设。现在只需决定是将本地时间存储在您的核心数据存储中,还是始终存储经过清理的时间(例如 UTC)。在获取或设置值时转换值,甚至使用 NSValueTransformer 将属性类型设置为 Transformable,该 NSValueTransformer 将当前本地时间转换为 UTC。
    • 听起来你是在美国 MNT 时间? /我检查你的个人资料......是的,墨西哥。 :-) 就个人而言,当序列化或存储在数据库(或 Core Data 之类的东西)中时,我更喜欢将日期转换为 UTC——上面的 17:00(v. 10:00)。现在,当您使用 Core Data 读出数据时,您有两个选择——在 getter 中“本地化”时间,在 setter 中“utc-ify”,或者使用 Transformable 类型和 NSValueTranformer 做同样的事情事物。在这种情况下,您可能会使用 NSPredicates 来搜索日期,我会坚持使用 NSDate 类型并使用 getter/setter 方法。 1/2
    • 2/2 ... 可转换类型不太容易被搜索——相等性容易,对于大于或小于等概念则不太容易。您可能需要转换的日期比您想象的要少(然后我最初想到的)......实际上您只需要在显示日期时更改日期的显示(通过 NSDateFormatter)。但是您可能需要一个内部助手来在搜索时转换日期。好的部分是,如果您存储在 GMT/UTC(NSDate 的默认值),那么如果用户碰巧跨时区,应用程序将“正常工作”。
    • 感谢您的宝贵时间和精彩的解释。这一切都意味着我将日期存储在 GMT/UTC 中,考虑到我上面提到的方法,我是否也在 GMT/UTC 中对项目进行排序?
    猜你喜欢
    • 2011-02-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多