Latest 0.2.0
License Public Domain
Platforms ios 8.0

YapTaskQueue Build Status

A persistent serial queue based on YapDatabase.



To setup create a handler and then register the handler with a name. Then in the block return if a given queueName is handled by this handler. If a queue is registered to multiple handler this will result in unpredictable behavior because they may both start the action but completion may complete with different results.

  let database = YapDatabase(path: path)
  let handler = //Some object that conforms to YapTaskQueueHandler
  let broker = try! YapTaskQueueBroker.setupWithDatabase(database, name: "handler1", handler: handler) { (queueName) -> Bool in
            // return true here if it's a queue that this handler understands and 'handles'
            return true
  // Or instead of checking the queue name in a closure you can just use the broker name as the prefix to a queue.
  // So in this case any actionItem that returns a queue starting with "handler1" like "handler1-queue2"

  let broker = try! YapTaskQueueBroker.setupWithDatabase(database, name: "handler1", handler: handler)

Creating an action

An action object should only hold the minimal information necessary for the corresponding YapTaskQueueHandler to know what to do if it’s instructed to handle it.


This is what a simple message send action might look like

class MessageSendAction:NSObject, NSCoding, YapTaskQueueAction {
    let key:String
    let collection:String
    let messageToSendKey:String
    let messagetoSendCollection:String
    let queue:String
    let date:NSDate

    init(key:String, collection:String, messageToSendKey:String,messagetoSendCollection:String, queue:String, date:NSDate) {
        self.key = key
        self.collection = collection
        self.messageToSendKey = messageToSendKey
        self.messagetoSendCollection = messagetoSendCollection
        self.queue = queue = date

    //MARK: YapTaskQueueAction
    func yapKey() -> String {
        return self.key

    func yapCollection() -> String {
        return self.collection

    func queueName() -> String {
        return self.queue

    func sort(otherObject: YapTaskQueueAction) -> NSComparisonResult {
        guard let otherAction = otherObject as? MessageSendAction else {
            return .OrderedSame


    //MARK: NSCoding

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.key, forKey: "key")
        aCoder.encodeObject(self.collection, forKey: "collection")
        aCoder.encodeObject(self.messageToSendKey, forKey: "messageToSendKey")
        aCoder.encodeObject(self.messagetoSendCollection, forKey: "messagetoSendCollection")
        aCoder.encodeObject(self.queue, forKey: "queue")
        aCoder.encodeObject(, forKey: "date")

    required convenience init?(coder aDecoder: NSCoder) {
        guard let key = aDecoder.decodeObjectForKey("key") as? String,
        let collection = aDecoder.decodeObjectForKey("collection") as? String,
        let messageToSendKey = aDecoder.decodeObjectForKey("messageToSendKey") as? String,
        let messagetoSendCollection = aDecoder.decodeObjectForKey("messagetoSendCollection") as? String,
        let queue = aDecoder.decodeObjectForKey("queue") as? String,
        let date = aDecoder.decodeObjectForKey("date") as? NSDate
            else {
                return nil

        self.init(key:key,collection: collection, messageToSendKey: messageToSendKey, messagetoSendCollection: messagetoSendCollection, queue: queue, date: date)

Here’s a rough outline of a message handler:

class MessageHandler:YapTaskQueueHandler {

    var databaseConnection:YapDatabaseConnection?

    func handleNextItem(action: YapTaskQueueAction, completion: (success: Bool, retryTimeout: NSTimeInterval) -> Void) {
        guard let messageAction = action as? MessageSendAction else {
            completion(success: false, retryTimeout: -1)

         1. Get the 'real' message out of the database
         2. Send the message over the wire
         3. get result

        let result = true
        If the sending was successful then return true and it doesn't matter what you set the `retryTimeout` to
        If the sending was not successful then send bask false and when you want to retry
        It's also possible to set the retry timeout to -1 if you don't want a timed retry but would rather manually retry when the conditions are more likely to result in a success

        completion(success: result, retryTimeout: 5)
        completion(success: result, retryTimeout: -1)

Once the broker and hanlder are setup with the database just by saving an action it will be processed in the queue. It’s not recomended to remove an action from within the handler. Rather when an action is completed as successful then the broker removes the action from the database and checks for remaining actions.

Latest podspec

    "name": "YapTaskQueue",
    "version": "0.2.0",
    "summary": "A persistent serial queue based on YapDatabase",
    "description": "A persistent serial queue based on YapDatabase. This makes it possible to create a persistent queue of 'actions'nthat can be dealt with between launches.",
    "homepage": "",
    "license": {
        "type": "Public Domain",
        "file": "LICENSE"
    "authors": {
        "David Chiles": "[email protected]"
    "platforms": {
        "ios": "8.0"
    "source": {
        "git": "",
        "tag": "0.2.0"
    "default_subspecs": "Standard",
    "pushed_with_swift_version": "3.0",
    "subspecs": [
            "name": "Standard",
            "source_files": "YapTaskQueue/Classes/**/*.swift",
            "dependencies": {
                "YapDatabase": [
                    "~> 2.9"
            "name": "SQLCipher",
            "source_files": "YapTaskQueue/Classes/**/*.swift",
            "dependencies": {
                "YapDatabase/SQLCipher": [
                    "~> 2.9"

Pin It on Pinterest

Share This