我有一个计划缓存存储在NSDictionary中。

对于下面的示例,我的计划时间为 2012年1月13日2:00 PM 2012年1月13日2:05 PM 。如何将两者都添加到队列中以自行触发?

构建计划缓存:

-(void) buildScheduleCache
{
    NSCalendarDate *now = [NSCalendarDate calendarDate];

    NSFileManager *manager = [[NSFileManager defaultManager] autorelease];
    path = @"/var/mobile/Library/MobileProfiles/Custom Profiles";
    theProfiles = [manager directoryContentsAtPath:path];

    myPrimaryinfo = [[NSMutableArray arrayWithCapacity:6] retain];
    keys = [NSArray arrayWithObjects:@"Profile",@"MPSYear",@"MPSMonth",@"MPSDay",@"MPSHour",@"MPSMinute",nil];

    for (NSString *profile in theProfiles)
    {
        plistDict = [[[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",path,profile]] autorelease];

        [myPrimaryinfo addObject:[NSDictionary dictionaryWithObjects:
                                  [NSArray arrayWithObjects:
                                   [NSString stringWithFormat:@"%@",profile],
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSYear"]],
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSMonth"]],
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSDay"]],
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSHour"]],
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSMinute"]],
                                   nil]forKeys:keys]];

        profileSched =
        [NSCalendarDate dateWithYear:[plistDict objectForKey:@"MPSYear"]
                               month:[plistDict objectForKey:@"MPSMonth"]
                                 day:[plistDict objectForKey:@"MPSDay"]
                                hour:[plistDict objectForKey:@"MPSHour"]
                              minute:[plistDict objectForKey:@"MPSMinute"]
                              second:01
                            timeZone:[now timeZone]];

        [self rescheduleTimer];
    }

    NSString *testPath = @"/var/mobile/Library/MobileProfiles/Schedules.plist";
    [myPrimaryinfo writeToFile:testPath atomically:YES];
}

安排 Activity :
-(void) scheduleProfiles
{
    NSFileManager *manager = [[NSFileManager defaultManager] autorelease];
    path = @"/var/mobile/Library/WrightsCS/MobileProfiles/Custom Profiles";
    theProfiles = [manager contentsOfDirectoryAtPath:path error:nil];

    for (NSString *profile in theProfiles)
    {
        NSMutableDictionary * plistDict = [[[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",path,profile]] autorelease];

        profileSched =
        [NSCalendarDate dateWithYear:[[plistDict objectForKey:@"MPSYear"] intValue]
                               month:[[plistDict objectForKey:@"MPSMonth"] intValue]
                                 day:[[plistDict objectForKey:@"MPSDay"] intValue]
                                hour:[[plistDict objectForKey:@"MPSHour"] intValue]
                              minute:[[plistDict objectForKey:@"MPSMinute"] intValue]
                              second:01
                            timeZone:[NSTimeZone localTimeZone]];


            NSLog(@"DATE: %@      SCHEDULE: %@      PROFILE: %@",[NSDate date],profileSched,profile);
        if([NSDate date] < profileSched)
        {
            NSLog(@"IGNORING PROFILE: %@     WITH SCHEDULE: %@",profile,profileSched);
        }else{
            //Create the timer from the Cached Array
            schedTimer = [[NSTimer alloc] initWithFireDate:profileSched //[NSDate dateWithTimeIntervalSinceNow: 10]
                                                  interval:0.1f
                                                    target:self
                                                  selector:@selector(fireCustomProfile:)
                                                  userInfo:profile
                                                   repeats:NO];//[[plistDict objectForKey:@"MPSRepeat"] boolValue]];

            MLogString(@"Scheduling Profile: %@",profile);
            [[NSRunLoop currentRunLoop] addTimer:schedTimer forMode:NSDefaultRunLoopMode];
        }
    }
}

触发事件:
-(void)fireCustomProfile:(NSTimer *)timer
{
    if([[NSDate date] earlierDate:[schedTimer fireDate]])
    {
        NSLog(@"Ignoring Profile: %@",[schedTimer userInfo]);
        return;
    }

    notify_post("com.wrightscs.MobileProfiles.setCustomProfile");
}

事件示例:
<array>
    <dict>
        <key>MPSDay</key>
        <string>13</string>
        <key>MPSHour</key>
        <string>21</string>
        <key>MPSMinute</key>
        <string>15</string>
        <key>MPSMonth</key>
        <string>1</string>
        <key>MPSYear</key>
        <string>2012</string>
        <key>Profile</key>
        <string>Event 1</string>
        <key>Repeat</key>
        <true/>
    </dict>
</array>
<array>
    <dict>
        <key>MPSDay</key>
        <string>13</string>
        <key>MPSHour</key>
        <string>21</string>
        <key>MPSMinute</key>
        <string>20</string>
        <key>MPSMonth</key>
        <string>1</string>
        <key>MPSYear</key>
        <string>2012</string>
        <key>Profile</key>
        <string>Event 2</string>
        <key>Repeat</key>
        <true/>
    </dict>
</array>

最佳答案

您可以使用UILocalNotification代替NSTimer。局限性在于,没有您的交互,您的应用程序中就不会执行任何操作,但是即使该应用程序已关闭,也会触发一条通知。

Apple有关UILocalNotifications的文档:

UILocalNotification实例表示有关以下内容的通知:
应用程序可以安排在特定时间向用户展示
日期和时间。操作系统负责交付
通知在适当的时间;该应用程序不必
为实现这一目标而奔波。

...

当系统传递本地通知时,可以做几件事
是否发生取决于应用程序状态和类型
通知。如果应用程序不是最前端且不可见,则
系统显示警报消息,标记应用程序并播放
声音-通知中指定的内容。如果通知
是警报,用户点击操作按钮(或者,如果设备是
锁定,拖动以打开操作滑块),将启动应用程序。在
application:didFinishLaunchingWithOptions:方法
委托可以从传入的对象中获取UILocalNotification对象
使用选项字典
UIApplicationLaunchOptionsLocalNotificationKey键。代表可以
检查通知的属性,如果有则检查
在其userInfo字典中包含自定义数据,它可以访问
数据并进行相应处理。另一方面,如果当地
通知仅标记应用程序图标,并且用户
响应启动应用程序,
application:didFinishLaunchingWithOptions:方法被调用,但是没有
UILocalNotification对象包含在选项字典中。

如果应用程序是最重要的,并且在系统交付时可见
通知,不显示警报,没有图标标记,也没有声音
玩过的。但是,application:didReceiveLocalNotification:是
如果应用程序委托实现,则调用此方法。的
UILocalNotification实例被传递到此方法中,并且
委托可以检查其属性或从中访问任何自定义数据
userInfo字典。

您可以找到一个很好的教程here,其主要思想如下:

通知设置:

Class cls = NSClassFromString(@"UILocalNotification");
if (cls != nil) {
    UILocalNotification *notif = [[cls alloc] init];
    notif.fireDate = [datePicker date];
    notif.timeZone = [NSTimeZone defaultTimeZone];

    notif.alertBody = TEXT;
    notif.alertAction = LAUNCH_BUTTON;
    notif.soundName = UILocalNotificationDefaultSoundName;
    notif.applicationIconBadgeNumber = NOTIFICATIONS_REMAINING;

    NSDictionary *userDict = [NSDictionary dictionaryWithObject:CUSTOM_INFO
                                            forKey:kRemindMeNotificationDataKey];
    notif.userInfo = userDict;

    [[UIApplication sharedApplication] scheduleLocalNotification:notif];
    [notif release];
}

当应用程序未运行时(在应用程序委托中)处理修饰符:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    Class cls = NSClassFromString(@"UILocalNotification");
    if (cls) {
        UILocalNotification *notification = [launchOptions objectForKey:
                        UIApplicationLaunchOptionsLocalNotificationKey];

        if (notification) {
            NSString *reminderText = [notification.userInfo
                        objectForKey:kRemindMeNotificationDataKey];
           [viewController showReminder:reminderText];
        }
    }

    application.applicationIconBadgeNumber = NOTIFICATIONS_REMAINING_LESS_ONE;

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

前台应用程序(在应用程序委托中):
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

    UIApplicationState state = [application applicationState];
    if (state == UIApplicationStateInactive) {
        // Application was in the background when notification
        // was delivered.
    }
}

关于objective-c - 使用NSTimer安排多个日常事件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2632996/

10-13 04:04