Creating a continuous background thread in iOS

Abishek picture Abishek · Jun 25, 2012 · Viewed 15k times · Source

I have a requirement to create a background processor that works only when the App is in the active mode. I have tried to make a skelton of what I am trying to acheive but not able to get it to work.

I want this background Processor to go to sleep when the app goes to an inactive stage and resume when the app comes to an active mode. I have provided a skeleton of what I have done below. Can someone help me fix this.

AppDelegate.h

#import <Foundation/Foundation.h>

@class BackgroundProcessor;

@interface AppDelegate_iPhone : UIResponder<UIApplicationDelegate>{
    BackgroundProcessor* processor;
}

@property(nonatomic) BackgroundProcessor *processor;

@end

AppDelegate.m

#import "AppDelegate_iPhone.h"
#import "BackgroundProcessor.h"


@implementation AppDelegate_iPhone

@synthesize processor;

-(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    processor = [[BackgroundProcessor alloc]init];
    [processor Start];         
    return YES;
}

-(void) applicationDidEnterBackground:(UIApplication *)application
{
    [processor Sleep];
    NSLog(@"Entered Background"); 
}

-(void) applicationDidBecomeActive:(UIApplication *)application
{
    [processor Resume];
    NSLog(@"Became Active"); 
}
@end

BackgroundProcessor.h

#import <Foundation/Foundation.h>

@interface BackgroundProcessor : NSObject
{
    NSThread* processor;
}

@property (nonatomic) NSThread *processor;

-(void) Start;
-(void) Sleep;
-(void) workloop;
-(void) Resume;
@end

BackgroundProcessor.m

#import "BackgroundProcessor.h"

@implementation BackgroundProcessor
@synthesize processor;
-(id) init
{
    self = [super init];
    if(self)
    {
        processor = [[NSThread alloc] initWithTarget:self selector:@selector(workloop) object:nil];
    }
    return self;
}

-(void) Start
{
    if(processor)
        [processor start];
}

-(void) Sleep
{
    //    [processor 
    [NSThread sleepForTimeInterval: 0.1];
}

-(void) workloop
{
    NSLog(@"Background Processor Processing ....");  
    [NSThread sleepForTimeInterval:0.1];
}

- (void) Resume
{
    NSLog(@"Background Resuming ....");  
    [NSThread sleepForTimeInterval: 0.1];
}

I am not able to get the workloop to get it running continuosly. Appreciate if someone could help me solve why the background

Tried this after the advice from Joshua Smith

#import "BackgroundProcessor.h"

@implementation BackgroundProcessor

-(id) init
{
    self = [super init];
    if(self)
    {
        queue = [[NSOperationQueue alloc] init];
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(workloop) object:nil];
        [queue addOperation:operation];
    }
    return self;
}

-(void) workloop
{

    NSLog(@"Sleeping for 10 seconds");  
    sleep(10);
    NSLog(@"Background Processor Processing ....");  
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(workloop) object:nil];
    [queue addOperation:operation];
}

@end

Answer

Joshua Smith picture Joshua Smith · Jun 25, 2012

Unless there is some specific reason this has to be a discrete thread, I would recommend you use an GCD or an NSOperation Queue and produce and consume workers. This kind of long-running thread is going to be a real problem in an iOS app.

GCD tutorial:

http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial