用于长进程的iPhone计时器任务

时间:2013-03-09 06:50:48

标签: iphone objective-c xcode timer

当应用程序进入后台状态时,用于在后台运行的时间不起作用。以下是代码。

在AppDelegate.h中,

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    BOOL status;
    UIBackgroundTaskIdentifier bgTask;
}

在AppDelegate.m中

    - (void)applicationDidEnterBackground:(UIApplication *)application
{

    NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);

    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIBackgroundTaskInvalid;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{

        if ([application backgroundTimeRemaining] > 1.0) {
            // Start background service synchronously
            [[vController getInstance] run];

        }

        [application endBackgroundTask:self->bgTask];
        self->bgTask = UIBackgroundTaskInvalid;

    });
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);

    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIBackgroundTaskInvalid;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{

        if ([application backgroundTimeRemaining] > 1.0) {

            // Start background service synchronously
            [[vController getInstance] stopbackground];

        }

        [application endBackgroundTask:self->bgTask];
        self->bgTask = UIBackgroundTaskInvalid;

    });
}

在视图Controller.h中,

@interface vController : UIViewController <AVAudioPlayerDelegate>
-(void) run;
-(void) stopbackground;
-(void) getMessage:(NSTimer*)theTimer;;
+(vController*) getInstance;
@property (nonatomic,retain) NSTimer * timer;
@end

view controller.m,

@implementation vController
@synthesize timer;
vController *tvc;

- (void)viewDidLoad
{
    [super viewDidLoad];
    tvc = self;
    // Do any additional setup after loading the view, typically from a nib.
}

+ (vController*) getInstance
{
    return tvc;
}

- (void)stopbackground
{
    timer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(getMessage:) userInfo:nil repeats:YES];
}

- (void)run
{
    timer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(getMessage:) userInfo:nil repeats:YES];
}

- (void) getMessage:(NSTimer*) theTimer
{

    NSError *error;

    NSString *path = [[NSBundle mainBundle] pathForResource:@"alert" ofType:@"mp3"];
    AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
    if (theAudio == nil) {
        NSLog(@"%@", [error description]);
    }
    NSLog(@"Hi");
    theAudio.delegate = self;
    theAudio.numberOfLoops = 1;
    [theAudio play];
}

- (void) dealloc{
    [timer release];
    [super dealloc];
}

我在模拟器6.0上使用它

2 个答案:

答案 0 :(得分:0)

根据您的使用情况,这可能无法实现。也就是说,Apple不允许您在“后台”中执行代码,除非您执行以下任务之一:

  • 在后台播放用户可听内容的应用, 例如音乐播放器应用
  • 随时向用户通知其位置信息的应用,例如导航应用
  • 支持互联网协议语音(VoIP)的应用
  • 需要下载和处理新内容的报亭应用
  • 从外部附件接收定期更新的应用

阅读详情:http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

答案 1 :(得分:0)

通过创建实例,您可以在任何视图控制器中运行后台任务,如下所示:

//在YourViewController.h文件中声明以下内容。

+ (YourViewController *)getInstance;
- (void)run;
-(void)stopbackground;

//在YourViewController.m文件中定义Vollowing。

static  YourViewController *instance = NULL;

+(YourViewController *)getInstance {

    @synchronized(self) {
        if (instance == NULL) {
            instance = [[self alloc] init];
        }
    }
    return instance;
}


- (void)run

{
// strat Back ground task
}
-(void)stopbackground
{
// Stop Background task
}
AppDelegate.h文件中的

声明以下内容

UIBackgroundTaskIdentifier bgTask; 
AppDelegate.m文件中的

使用以下方法。

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"Application entered background state.");

    // bgTask is instance variable
    NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);

    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIBackgroundTaskInvalid;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{

        if ([application backgroundTimeRemaining] > 1.0) {
            // Start background service synchronously
[[YourViewController getInstance] run];

        }

        [application endBackgroundTask:self->bgTask];
        self->bgTask = UIBackgroundTaskInvalid;

    });
}


- (void)applicationWillEnterForeground:(UIApplication *)application
{

    NSLog(@"Application entered background state.");

    // bgTask is instance variable
    NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);

    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIBackgroundTaskInvalid;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{

        if ([application backgroundTimeRemaining] > 1.0) {

 // Start background service synchronously
  [[YourViewController getInstance] stopbackground];

        }

        [application endBackgroundTask:self->bgTask];
        self->bgTask = UIBackgroundTaskInvalid;

    });


    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}