使用NSTimer安排多个日常活动吗? [英] Schedule multiple, daily events with NSTimer?

查看:88
本文介绍了使用NSTimer安排多个日常活动吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a schedule cache stored in an NSDictionary.

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

For the example below, I have a schedule time of January 13, 20120 2:00PM and January 13, 2012 2:05PM. How can I add both of these to a queue to fire on their own?

-(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];
}

安排事件:

-(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.局限性在于,没有您的交互,您的应用程序中就不会执行任何操作,但是即使该应用程序已关闭,也会触发一条通知.

You can use UILocalNotification instead of NSTimer. The limitations are that there is no actions in your application without your interaction, but there is triggered a notification even if the app is shutted down.

有关 UILocalNotifications :

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

Instances of UILocalNotification represent notifications that an application can schedule for presentation to its users at specific dates and times. The operating system is responsible for delivering the notification at the proper time; the application does not have to be running for this to happen.

...

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

When the system delivers a local notification, several things can happen, depending on the application state and the type of notification. If the application is not frontmost and visible, the system displays the alert message, badges the application, and plays a sound—whatever is specified in the notification. If the notification is an alert and the user taps the action button (or, if the device is locked, drags open the action slider), the application is launched. In the application:didFinishLaunchingWithOptions: method the application delegate can obtain the UILocalNotification object from the passed-in options dictionary by using the UIApplicationLaunchOptionsLocalNotificationKey key. The delegate can inspect the properties of the notification and, if the notification includes custom data in its userInfo dictionary, it can access that data and process it accordingly. On the other hand, if the local notification only badges the application icon, and the user in response launches the application, the application:didFinishLaunchingWithOptions: method is invoked, but no UILocalNotification object is included in the options dictionary.

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

If the application is foremost and visible when the system delivers the notification, no alert is shown, no icon is badged, and no sound is played. However, the application:didReceiveLocalNotification: is called if the application delegate implements it. The UILocalNotification instance is passed into this method, and the delegate can check its properties or access any custom data from the userInfo dictionary.

您可以找到一个很好的教程这里的主要思想是这样的:

You can found a good tutorial here where the main idea is like this:

通知设置:

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];
}

在应用程序未运行时(在应用程序委托中)处理修饰符:

Handling the nofitication when the application is not running (in the applicaction delegate):

- (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;
}

前台(在应用程序委托中)中的应用程序:

Application in the foreground (in the applicaction delegate):

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

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

这篇关于使用NSTimer安排多个日常活动吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆