Skip to content
Lucas Nelaupe edited this page Jan 12, 2018 · 18 revisions

SwiftQueue is built on top of Operation and OperationQueue. It support multiple queues with concurrent run, failure/retry, persistence and more features.

Getting started

SwiftQueue is available on CocoaPod, Carthage and Swift Package Manager.

Cocoapod setup pod 'SwiftQueue'

Carthage setup github "lucas34/SwiftQueue"

Send tweet in order

In this following example we will schedule a job to send tweets. All jobs will run in sequence.

Create your first Queue

SwiftQueueManager requires only 1 argument: an array of creator. See Job Creation section.

let tweetQueueManager = SwiftQueueManager(creators: [TweetJobCreator()])

Insert job info to the queue

// Type is required to know which implementation of Job we should create
JobBuilder(type: SendTweetJob.type)
        // Prevent adding the same job multiple times
        .singleInstance(forId: String)
        // Different group name will run in parallel
        // But one by one for a group
        .group(name: "tweet")
        // Sending tweet will require internet. At least cellular. 
        // Will also be executed if connected to wifi.
        .internet(atLeast: .cellular)
        // Content of your tweet. Can be a class, struct or anything
        .with(params: ["value": "Hello TweetWorld"])
        // Retry maximum 5 times if the job fail before removing from the queue
        // No retry by default
        .retry(limit: .limited(5))
        // Cancel the job if it's not completed after 60 seconds
        .deadline(date: Date(timeIntervalSinceNow: 60))
        // Insert to queue
        .schedule(manager: tweetQueueManager)

Write your job execution code

class SendTweetJob: Job {
    
    public static let type = "SendTweetJob"

    private let tweetMessage: [String: Any]

    // Argument specified in JobBuilder.with()
    required init?(message: [String: Any]) {
        self.tweetMessage = message
    }

    func onRun(callback: JobResult) throws {
        // Actual sending is happening here
        API.sendTweet(type: "TEXT", content: tweetMessage)
        .onSucess {
            // Notify job done without error
            callback.done(.success)
        }.onFail { error in
            // Job failed.
            callback.done(.fail(error))
        }
    }

    func onRetry(error: Error) -> RetryConstraint {
       // When a job failed. Since we put retry(max: 5). 
       // This callback will be called at most 5 times
       // Specify if we still want to retry or not.
        if error is ApiError {
            // No need for retry, Server rejected the message.
            // Will remove job from queue even if retry counter > 0
            return RetryConstraint.cancel 
        } else {
            // Job will run again. Retry counter will decrease
            return RetryConstraint.retry(delay: 0)
        }
    }

    func onRemove(result: JobCompletion) {
        // Job is removed from queue
        // Update your UI or your database
    }
}

Last step, Linking

class TweetJobCreator: JobCreator {

    func create(type: String, params: [String: Any]?) -> Job? {
        // params as specified in JobBuilder.with()
        if type == SendTweetJob.type {
            // Return our actual job.
            return SendTweetJob(message: params)
        } else {
            // Nothing match
            return nil
        }
    }
}