Enabling PerformSelectorInBackground Functionality in iOS for Improved Performance

Understanding and Enabling PerformSelectorInBackground Functionality in iOS

Introduction

PerformSelectorInBackground is a function introduced by Apple to enable background tasks for iOS applications. The primary purpose of this functionality is to allow apps to perform certain tasks when the app is running in the background, thereby improving overall user experience.

In this article, we’ll delve into the concept of PerformSelectorInBackground, its usage, and how to enable it in your iOS application. We’ll explore various scenarios where this function can be useful and provide code examples to illustrate its implementation.

What is PerformSelectorInBackground?

PerformSelectorInBackground is a function that allows you to execute a selector (a method or block) on the background thread of an app running in the background state. The primary difference between PerformSelectorInBackground and PerformSelectorOnMainThread is that the former executes the selector on a background thread, while the latter executes it on the main thread.

When an app runs in the foreground, the main function is responsible for handling user interactions, networking, and other tasks that require immediate attention. However, when the app goes into the background, the system switches to a separate thread called the “background thread” or “system background thread,” which allows your app to continue performing certain tasks without disrupting the foreground app.

PerformSelectorInBackground is designed to help apps perform long-running operations in the background without blocking the main thread. By doing so, it improves overall performance, reduces battery consumption, and ensures a smoother user experience.

When to Use PerformSelectorInBackground?

PerformSelectorInBackground is most useful when you need to perform tasks that:

  1. Don’t affect the UI: If your task doesn’t interact with the user interface or requires significant processing power, use PerformSelectorInBackground.
  2. Can run concurrently: If your app can continue running other background tasks while performing a specific task, use PerformSelectorInBackground.

Some common examples of tasks that benefit from using PerformSelectorInBackground include:

  • Updating a server without blocking the main thread
  • Performing complex calculations in the background
  • Sending push notifications or remote notifications

Enabling PerformSelectorInBackground

To enable PerformSelectorInBackground, you need to configure your app’s Info.plist file.

Here are the steps to follow:

Step 1: Locate the relevant setting in Info.plist

Open your Xcode project and navigate to the Info.plist file. You’ll find a key called UIBackgroundModes.

Step 2: Add UIBackgroundModes to your app

In the UIBackgroundModes section, add a new value of “background” to enable PerformSelectorInBackground.

Here’s what it should look like:

<key>UIBackgroundModes</key>
<array>
    <string>background</string>
</array>

Step 3: Modify your code

Modify your code to use PerformSelectorInBackground instead of PerformSelectorOnMainThread or PerformSelectorInBackground.

For example, let’s say you have a function called backgroundTask that performs some long-running operation:

-(void)backgroundTask {
    @try {
        // Perform your task here...
        
    } @catch (NSException *exception) {
        [CommonMethods logException:@"NetworkHandler - backgroundTask" :exception :@"NetworkHandler"];
    }
}

Now, let’s modify it to use PerformSelectorInBackground:

-(void)backgroundTask {
    @try {
        // Perform your task here...
        
    } @catch (NSException *exception) {
        [CommonMethods logException:@"NetworkHandler - backgroundTask" :exception :@"NetworkHandler"];
    }
}

However, if you want to call backgroundTask from another thread using PerformSelectorInBackground, use this code instead:

-(void)callBackgroundTaskFromBackground {
    @try {
        [_self performSelectorInBackground:@selector(backgroundTask)];
        
    } @catch (NSException *exception) {
        [CommonMethods logException:@"NetworkHandler - callBackgroundTaskFromBackground" :exception :@"NetworkHandler"];
    }
}

Code Example

Here’s a complete code example that demonstrates how to use PerformSelectorInBackground:

#import <Foundation/Foundation.h>

@interface NetworkHandler : NSObject

@property (nonatomic, strong) id _delegate;

- (void)sendServerCall:(NSDictionary *)data {
    [self performSelectorInBackground:@selector(onBackground:) withObject:data];
}

-(void)onBackground:(NSDictionary *)data {
    @try {
        NSString *result = [NSString stringWithFormat:@"%@%@", [data objectForKey:Dictionary_Keys_Method], Dictionary_Keys_ResultVal];
        int delegateKey = [[data objectForKey:Dictionary_Keys_Delegate] integerValue];
        NSURL *serviceUrl = [NSURL URLWithString:[data objectForKey:Dictionary_Keys_WebServiceUrl]];
        NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:serviceUrl];
        NSString *msgLength = [NSString stringWithFormat:@"%lu",(unsigned long)[[data objectForKey:Dictionary_Keys_SopaMessage] length]];
        [theRequest addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
        [theRequest addValue:[NSString stringWithFormat:@"%@%@", [data objectForKey:Dictionary_Keys_WebServiceNameSpace],[data objectForKey:Dictionary_Keys_Method]] forHTTPHeaderField:@"SOAPAction"];
        [theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];
        [theRequest setHTTPMethod:@"POST"];
        [theRequest setHTTPBody:[[data objectForKey:Dictionary_Keys_SopaMessage] dataUsingEncoding:NSUTF8StringEncoding]];
        
        NSURLConnection *theConnection = [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
        if (theConnection) {
            NSMutableData *_conWebData = [NSMutableData data];
            _conWebData = [_conWebData mutableCopy];
        } else {
            // Call backgroundTask from the main thread
            [self callBackgroundTaskFromMainThread];
        }
        
    } @catch (NSException *exception) {
        [CommonMethods logException:@"NetworkHandler - onBackground" :exception :@"NetworkHandler"];
    }
}

- (void)callBackgroundTaskFromMainThread {
    // Call backgroundTask from the main thread using PerformSelectorOnMainThread
    [self performSelectorOnMainThread:@selector(backgroundTask)];
}

-(void)backgroundTask {
    @try {
        // Perform your task here...
        
    } @catch (NSException *exception) {
        [CommonMethods logException:@"NetworkHandler - backgroundTask" :exception :@"NetworkHandler"];
    }
}

Conclusion

PerformSelectorInBackground is a powerful feature introduced by Apple that allows you to execute tasks in the background, improving overall user experience and performance. By enabling this functionality in your app’s Info.plist file and modifying your code accordingly, you can take advantage of PerformSelectorInBackground.

Always remember to call backgroundTask from the main thread when it’s necessary to ensure proper execution on both threads.

This article covered the basics of PerformSelectorInBackground, its usage, and how to enable it in your iOS app.


Last modified on 2024-08-19