AppDelegate.h
#import <UIKit/UIKit.h>
@interface AppDelegate : NSObject {
// Instance member of our background task process
UIBackgroundTaskIdentifier bgTask;
}
@end
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
[[BackgroundCleanupService getInstance] run];
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
В приведенной выше реализации есть пара ключевых строк:
Первая — это строка bgTask = [application beginBackgroundTaskWithExpirationHandler..., которая запрашивает дополнительное время для запуска задач очистки в фоновом режиме.
Второй — это последний блок кода метода делегата, начинающийся с dispatch_async. По сути, это проверка того, осталось ли время для выполнения операции с помощью вызова [application backgroundTimeRemaining]
. В этом примере я хочу запустить фоновую службу один раз, но в качестве альтернативы вы можете использовать цикл, проверяющий backgroundTimeRemaining на каждой итерации.
Строка [[BackgroundCleanupService getInstance] run] будет вызовом нашего одноэлементного класса обслуживания, который мы создадим прямо сейчас.
Теперь, когда делегат приложения готов запустить нашу фоновую задачу, нам нужен класс службы, который будет взаимодействовать с веб-сервером. В следующем примере я отправлю фиктивный сеансовый ключ и проанализирую ответ, закодированный в формате JSON. Кроме того, я использую две полезные библиотеки для выполнения запроса и десериализации возвращенного JSON, а именно JSONKit и ASIHttpRequest.
BackgroundCleanupService.h
#import <Foundation/Foundation.h>
@interface BackgroundCleanupService : NSObject
+ (BackgroundCleanupService *)getInstance;
- (void)run;
@end
BackgroundCleanupService.m
#import "BackgroundCleanupService.h"
#import "JSONKit.h"
#import "ASIHTTPRequest.h"
@implementation BackgroundCleanupService
/*
* The singleton instance. To get an instance, use
* the getInstance function.
*/
static BackgroundCleanupService *instance = NULL;
/**
* Singleton instance.
*/
+(BackgroundCleanupService *)getInstance {
@synchronized(self) {
if (instance == NULL) {
instance = [[self alloc] init];
}
}
return instance;
}
- (void)run {
NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.example.com/user/%@/endsession", @"SESSIONKEY"]];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:URL];
[request setTimeOutSeconds:20]; // 20 second timeout
// Handle request response
[request setCompletionBlock:^{
NSDictionary *responseDictionary = [[request responseData] objectFromJSONData];
// Assume service succeeded if JSON key "success" returned
if([responseDictionary objectForKey:@"success"]) {
NSLog(@"Session ended");
}
else {
NSLog(@"Error ending session");
}
}];
// Handle request failure
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(@"Service error: %@", error.localizedDescription);
}];
// Start the request synchronously since the background service
// is already running on a background thread
[request startSynchronous];
}
@end
может помочь
person
Maulik shah
schedule
17.12.2015