测试已测试 | ✓ |
语言语言 | Obj-CObjective C |
许可 | MIT |
发布最后发布 | 2015年6月 |
由 Valerius 维护。
依赖 | |
VinylRecord | >= 0 |
JSONKit-NoWarning | ~> 1.2 |
Reachability | ~> 3.2 |
MSWeakTimer | ~> 1.1.0 |
iDelayedJob(或 iDJ,类似于 Jazzy Jeff)是一个作业调度器,允许透明地执行和重试任务,直到成功或耗尽,即使在应用程序重启时也是如此,并受类似名称的 rust 插件的启发。
它从涉及发送评论和其他需要连接到后端服务(但由于各种原因,例如连接丢失甚至后端当时不可用)的任务的项目的功能中提取出来。使用 iDelayedJob,您可以安排一个作业来执行某些操作,例如注册评论或使用内部高级货币进行购买等,这将根据计划进行多次尝试,根据计划说,只有当根据 Reachability 确定连接可用时才尝试此作业,从而不尝试在找不到互联网的情况下需要互联网的作业。
要运行示例项目,克隆仓库,然后首先从 Example 目录运行 pod install
。
注意:iDelayedJob 已重构为使用 VinylRecord(Alex Denisov 的 iActiveRecord 分支)作为作业存储和查询的持久化层。因此,如果您也使用 VinylRecord,确保您在使用任何作业之前,为主应用程序配置数据库,以确保应用程序设置优先于与 iDelayedJob 一起使用的默认设置。
iDelayedJob 可通过 CocoaPods 获得。要安装它,只需将以下行添加到 Podfile。
pod "iDelayedJob"
为了使用类,您必须包含 DelayedJob.h 头文件。
在安排作业之前,您必须先定义它,方法是通过继承 NLDelayableJob 或创建一个实现了 NLDelayableJobAbility 协议的类。两种方法都将执行 perform 方法,该方法将返回作业是否成功完成。如果没有成功完成,作业将在指定的 max_attempts 期间定期执行,一旦达到最大尝试次数,则将作业从队列中删除。
继承 NLDelayableJob(或者 DelayableJob 宏允许删除 NL 前缀,以获取核心类)
#import "DelayedJob.h"
@interface NLPrimaryJob : NLDelayableJob
@end
@implementation NLPrimaryJob {}
- (BOOL)perform {
NSLog(@"job=%@ queue=%@ attempts=%@ nextRun=%@",self.handler,self.queue,self.attempts,self.run_at);
// Perform work and return YES if work was successful. This can included connecting to backend server, etc.
return YES;
}
@end
或实现协议
@protocol NLDelayableJobAbility <NSObject>
@required
+ (BOOL) performJob: (NLJobDescriptor*) descriptor withArguments: (NSArray *)arguments;
@optional
+ (NSDate*) scheduleJob: (NLJobDescriptor*) descriptor withArguments: (NSArray *)arguments;
+ (BOOL) shouldRestartJob: (NLJobDescriptor*) descriptor withArguments: (NSArray *)arguments;
+ (void) beforeDeleteJob: (NLJobDescriptor*) descriptor withArguments: (NSArray *)arguments;
@end
例如
#import "DelayedJob.h"
@interface NLAbilityJob : NSObject <NLDelayableJobAbility>
@end
@implementation NLAbilityJob {}
+ (BOOL)performJob:(NLJobDescriptor *)descriptor withArguments:(NSArray *)arguments {
NLDelayableJob *job = descriptor.job;
// Perform work and return YES if work was successful. This can included connecting to backend server, etc.
return NO;
}
+ (NSDate *)scheduleJob:(NLJobDescriptor *)descriptor withArguments:(NSArray *)arguments {
NLDelayableJob *job = descriptor.job;
NSInteger add_seconds = ([job.attempts intValue] + 5) * 4; // Default equation for job scheduling
NSDate *nextRunTime = [NSDate dateWithTimeIntervalSinceNow:(int) add_seconds];
return nextRunTime; // Normal job schedule can be changed if you return a different date.
}
+ (BOOL)shouldRestartJob:(NLJobDescriptor *)descriptor withArguments:(NSArray *)arguments {
NLDelayableJob *job = descriptor.job;
NSLog(@"shouldRestartJob: job=%@ : %@ queue=%@ attempts=%@ nextRun=%@",job.handler,job.job_id,job.queue,job.attempts,job.run_at);
return NO; //Job will be deleted if 'NO' is returned.
}
+ (void)beforeDeleteJob:(NLJobDescriptor *)descriptor withArguments:(NSArray *)arguments {
NLDelayableJob *job = descriptor.job;
return;
}
@end
NLDelayedJob 表示配置期间运行的队列,您可以有多个作业队列,但是每个队列名称必须是唯一的,否则在启动作业时将引发异常。您最关心的主要参数是 max_attempts,它指定在放弃之前失败作业将运行多少次,interval 决定队列运行寻找待运行的作业的频率,以及必须唯一的 queue 名称。
定义如下
@interface NLDelayedJob : NSObject {}
@property(nonatomic, assign) NSInteger max_attempts;
@property(nonatomic, assign) NSTimeInterval interval;
@property(nonatomic, readonly) NSString *queue;
#pragma mark - Initialization
+ (instancetype)queueWithName:(NSString *)name interval:(NSTimeInterval)interval attemps:(NSInteger)attempts;
- (id)initWithQueue:(NSString *)name interval:(NSTimeInterval)interval attemps:(NSInteger)attempts;
+ (NLDelayedJob *)configure:(NLDelayedJobConfigurationBlock)config;
#pragma mark - Singleton Helpers
+ (NLDelayedJob *)defaultQueue;
+ (NLDelayedJobManager *)sharedManager;
#pragma mark - Instance Methods
- (NLDelayedJob *)start; //starts timers and job processing
- (void)pause; // Prevents new jobs from being processed
- (void)resume; // Allows new jobs to be pull from queue and executed
- (void)stop; // shuts down timers
- (NLDelayableJob *)scheduleInternetJob:(NLDelayableJob *)job priority:(NSInteger)priority;
- (NLDelayableJob *)scheduleJob:(NLDelayableJob *)job priority:(NSInteger)priority internet:(BOOL)requireInternet;
- (NLDelayableJob *)scheduleJob:(NLDelayableJob *)job priority:(NSInteger)priority;
@end
尽管您可以在任何地方实例化队列,但是在 Application Delegate 中启动和停止队列并使其在整个应用程序运行期间运行,这更有意义。
例如
#import "DelayedJob.h"
@implementation NLAppDelegate {
NLDelayedJob *primaryQueue;
NLDelayedJob *secondaryQueue ;
NLDelayedJob *thirdQueue ;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Create/Start Method 1: Create Queue Using configure method which may offer more options than designated initializer.
primaryQueue =[[NLDelayedJob configure:^(NLDelayedJobConfiguration *config) {
config.queue = @"PrimaryQueue";
config.max_attempts = 3;
}] start];
// Create/Start Method 2: Use initializer to create and subsequently start the queue using the specified options
secondaryQueue = [[NLDelayedJob queueWithName:@"SecondaryQueue" interval:10 attemps:4] start];
// Create/Start Method 3: // same as above but with macro allowing dropping of NL prefix
thirdQueue = [DelayedJob configure(^(NLDelayedJobConfiguration *config) {
config.queue = @"PrimaryQueue";
config.max_attempts = 3;
}) start];
return YES;
}
如果您希望在某个 UIViewController 的上下文中仅存在队列,则在释放过程中务必要停止队列,否则队列无法释放,因为在运行时它也被 NLDelayedJobManager 保存在。
一旦定义了一个作业并启动了一个队列,它就可以被安排运行。
例如
#import "DelayedJob.h"
@implementation SomeClassWhichLikesQueues
- (void) scheduleQueues
// Schedule Method 1: Assumes secondaryQueue (defined someplace) contains a running queue
[secondaryQueue scheduleJob:[NLDelayableJob jobWithClass:[NLAbilityJob class]]
priority:NLDelayedJobPriorityNormal];
// Schedule Method 2: No need to store variable with unique Queue Name. You may schedule using shared Manager.
[[NLDelayedJob sharedManager] scheduleJob:[NLSecondaryJob new]
queue:@"PrimaryQueue"
priority:NLDelayedJobPriorityMedium
internet:NO]; //Internet not required to attempt processing job
// Schedule Method 3: Same as method above, but uses terse macro
DelayedJob_schedule([NLSecondaryJob class], @"PrimaryQueue", NLDelayedJobPriorityMedium,@"Arg1",@"Arg2");
}
end
iDelayedJob 适用于 MIT 许可。有关更多信息,请参阅 LICENSE 文件。