• Stars
    star
    679
  • Rank 63,928 (Top 2 %)
  • Language
    Swift
  • License
    MIT License
  • Created almost 10 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Task Queue Class developed in Swift (by Marin Todorov)

TaskQueue

Platform Cocoapods Compatible Carthage Compatible GitHub License

Table of Contents

Intro

title

TaskQueue is a Swift library which allows you to schedule tasks once and then let the queue execute them in a synchronous manner. The great thing about TaskQueue is that you get to decide on which GCD queue each of your tasks should execute beforehand and leave TaskQueue to do switching of the queues as it goes.

Even if your tasks are asynchronious like fetching location, downloading files, etc. TaskQueue will wait until they are finished before going on with the next task.

Last but not least your tasks have full flow control over the queue, depending on the outcome of the work you are doing in your tasks you can skip the next task, abort the queue, or jump ahead to the queue completion. You can further pause, resume, and stop the queue.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

If you don't already have the Cocoapods gem installed, run the following command:

$ gem install cocoapods

To integrate TaskQueue into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'TaskQueue'

Then, run the following command:

$ pod install

If you find that you're not having the most recent version installed when you run pod install then try running:

$ pod cache clean
$ pod repo update TaskQueue
$ pod install

Also you'll need to make sure that you've not got the version of TaskQueue locked to an old version in your Podfile.lock file.

Carthage

Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate TaskQueue into your Xcode project using Carthage, specify it in your Cartfile:

github "icanzilb/TaskQueue"

Simple Example

Synchronous tasks

Here's the simplest way to use TaskQueue in Swift:

let queue = TaskQueue()

queue.tasks +=~ {
	... time consuming task on a background queue...
}

queue.tasks +=! {
	... update UI on main queue ...
}

queue.run()

TaskQueue will execute the tasks one after the other waiting for each task to finish and the will execute the next one. By using the operators +=~ and +=! you can easily set whether the task should execute in background or on the main queue.

Asynchronous tasks

More interesting of course is when you have to do some asynchronous work in the background of your tasks. Then you can fetch the next parameter in your task and call it whenever your async work is done:

let queue = TaskQueue()

queue.tasks +=~ { result, next in

    var url = URL(string: "http://jsonmodel.com")

    URLSession.shared.dataTask(with: url,
        completionHandler: { _, _, _ in
            // process the response
            next(nil)
        })
}

queue.tasks +=! {
    print("execute next task after network call is finished")
}

queue.run {
    print("finished")
}

There are a few things to highlight in the example above:

  1. The first task closure gets two parameters: result is the result from the previous task (nil in the case of the first task) and next. next is a closure you need to call whenver your async task has finished executing.

  2. Task nr.2 doesn't get started until you call next() in your previous task.

  3. The run function can also take a closure as a parameter - if you pass one it will always get executed after all other tasks has finished.

Serial and Concurrent Tasks

By default TaskQueue executes its tasks one after another or, in other words, the queue has up to one active task at a time.

You can, however, allow a given number of tasks to execute at the same time (e.g. if you need to download a number of image files from web). To do this just increase the number of active tasks and the queue will automatically start executing tasks concurrently. For example:

queue.maximumNumberOfActiveTasks = 10

This will make the queue execute up to 10 tasks at the same time.

Note: As soon as you allow for more than one task at a time certain restrictions apply: you cannot invoke retry(), and you cannot pass a result from one task to another.

GCD Queue Control

Do you want to run couple of heavy duty tasks in the background and then switch to the main queue to update your app UI? Easy. Study the example below, which showcases GCD queue control with TaskQueue:

let queue = TaskQueue()

//
// "+=" adds a task to be executed on the current queue
//
queue.tasks += {
    // update the UI
}

//
// "+=~" adds a task to be executed in the background, e.g. low prio queue
// "~" stands for so~so priority
//
queue.tasks +=~ {
    // do heavy work
}

//
// "+=!" adds a task to be executed on the main queue
// "!" stands for High! priority
//
queue.tasks +=! {
    // update the UI again
}

// to start the queue on the current GCD queue
queue.run()

Extensive example

let queue = TaskQueue()

//
// Simple sync task, just prints to console
//
queue.tasks += {
    print("====== tasks ======")
    print("task #1: run")
}

//
// A task, which can be asynchronious because it gets
// result and next params and can call next() when ready
// with async work to tell the queue to continue running
//
queue.tasks += { result, next in
    print("task #2: begin")

    delay(seconds: 2) {
        print("task #2: end")
        next(nil)
    }

}

//
// A task which retries the same task over and over again
// until it succeeds (i.e. util when you make network calls)
// NB! Important to capture **queue** as weak to prevent
// memory leaks!
//
var cnt = 1
queue.tasks += { [weak queue] result, next in
    print("task #3: try #\(cnt)")
    cnt += 1

    if cnt > 3 {
        next(nil)
    } else {
        queue!.retry(delay: 1)
    }
}

//
// This task skips the next task in queue
// (no capture cycle here)
//
queue.tasks += {
    print("task #4: run")
    print("task #4: will skip next task")

    queue.skip()
}

queue.tasks += {
    print("task #5: run")
}

//
// This task removes all remaining tasks in the queue
// i.e. util when an operation fails and the rest of the queueud
// tasks don't make sense anymore
// NB: This does not remove the completions added
//
queue.tasks += {
    print("task #6: run")

    print("task #6: will append one more completion")
    queue.run { _ in
        print("completion: appended completion run")
    }

    print("task #6: will skip all remaining tasks")
    queue.removeAll()
}

queue.tasks += {
    print("task #7: run")
}

//
// This either runs or resumes the queue
// If queue is running doesn't do anything
//
queue.run()

//
// This either runs or resumes the queue
// and adds the given closure to the lists of completions.
// You can add as many completions as you want (also half way)
// trough executing the queue.
//
queue.run { result in
    print("====== completions ======")
    print("initial completion: run")
}

Run the included demo app to see some of these examples above in action.

Credit

Author: Marin Todorov

License

TaskQueue is available under the MIT license. See the LICENSE file for more info.

More Repositories

1

EasyAnimation

A Swift library to take the power of UIView.animateWithDuration(_:, animations:...) to a whole new level - layers, springs, chain-able animations and mixing view and layer animations together!
Swift
2,963
star
2

SwiftSpinner

A beautiful activity indicator and modal alert written in Swift (originally developed for my app DoodleDoodle) Using blur effects, translucency, flat and bold design - all iOS 8 latest and greatest
Swift
2,158
star
3

Timelane

Timelane
Swift
700
star
4

UIEffectDesignerView

A native Particle Systems effect view for iOS and OSX powered by QuartzCore
Objective-C
616
star
5

Retry

Haven't you wished for `try` to sometimes try a little harder? Meet `retry`
Swift
498
star
6

EventBlankApp

A free open source iOS app for events or conferences. Read more on the app's webpage:
Swift
291
star
7

MTLog

NSLog replacement for coders!
Objective-C
222
star
8

Breadcrumbs

Bugtracker working off source code
Swift
185
star
9

TimelaneCombine

Timelane + Combine
Swift
167
star
10

RxTimelane

Timelane + RxSwift
Swift
132
star
11

PowerUpYourAnimations

Sample code from talks on advanced animations
Swift
118
star
12

DoNilDisturbPlugin

A plugin for your Xcode project that stops you from working outside work hours
Swift
110
star
13

timeui

Profile apps from the command line — duration, cpu & memory usage.
Swift
108
star
14

OneShotLocationManager

A replacement class for CLLocationManager for when you want to easily fetch the current device location
Swift
102
star
15

MTPopupWindow

Popup-window style view for Objective-C, which loads contents of an HTML file. Easy one-line usage. Check the readme for example
Objective-C
84
star
16

TimelaneCore

Timelane + Core
Swift
66
star
17

OperationTimelane

Timelane + Operations
Swift
45
star
18

RxSwiftoniOS

Sample code from my dotSwift 2017 talk in Paris
Swift
43
star
19

PackageView

An app that displays Package.swift info
Swift
41
star
20

RealmGitHubSearchRxDemo

The demo app for RxRealm's post on realm.io
Swift
36
star
21

RealmMultiplatformDemo

Demo that shares its model layer across Apple's four platforms
Swift
36
star
22

Advanced-RSS-reader

An example of an RSS reader app for iPhone, full source and comments
Objective-C
34
star
23

MTTestSemaphore

A class to help you create unit tests that test asynchronous methods. You will need this to unit test any class that fetch data from the network, use location, camera, etc.
Objective-C
33
star
24

Cancellor

Bind multiple cancellables to the lifetime of another object like a view controller.
Swift
32
star
25

RealmNotificationExample

The project for the post demonstrating fine grained notifications on realm.io
Swift
30
star
26

Unxippity

Unxips quickly Xcode downloads
Swift
30
star
27

HUD

Beautiful alert message/ progress hud component for iOS Objective-C
Objective-C
25
star
28

MarkWalkthrough

A SwiftUI package to quickly build app walkthroughs
Swift
24
star
29

SafariDownload

Swift package to read Safari's download packages
Swift
8
star
30

CustomInstrument

A custom Xcode instrument based on Timelane
Swift
7
star
31

Fetch-and-parse-JSON

Fetch and parse JSON
Objective-C
7
star
32

ActorBench

Actor vs queue vs lock benchmark
Swift
6
star
33

TimelaneInstrument

Timelane Tools Instrument
5
star
34

StylesDemoApp

A little experiment on styling SwiftUI views
Swift
4
star
35

powerups

cli for dynamic XML includes
Swift
3
star
36

nsspain2020

Demo projects from my talk at NSSpain 2020
Swift
3
star
37

Tracker

Google Analytics iOS shortcut wrapper
3
star
38

TimerApp

Timer App v1
Swift
3
star
39

LogRider

Logs viewer app for mac
Swift
3
star
40

snippetty.io

snippetty.io
HTML
3
star
41

HTTPKit

Task based, promise like syntax, RESTful, HTTP library for iOS and OS X. Built off ConcurrentKit and NSURLSession.
Objective-C
2
star
42

react-native-console-oslog

React Native package to log to Apple's unified log
Objective-C++
2
star
43

rx-marin

rx blog:
HTML
2
star
44

ALAssetsLibrary-CustomPhotoAlbum

A nice ALAssetsLibrary category for saving images & videos into custom photo album. by @MarinTodorov.
Objective-C
2
star
45

combinebook.com

HTML
2
star
46

ios-animations-by-emails

iOS Animations by Emails newsletter archive
HTML
2
star
47

snippety.io

snippetty.io
1
star
48

swiftconcurrencybook

swiftconcurrencybook.com
CSS
1
star
49

AnagramsGameiPad

The completed source code to "How to create an awesome Anagrams game with UIKit"
Objective-C
1
star
50

Baffle

Ruby
1
star
51

www.timelane.tools

www.timelane.tools
1
star
52

macro-bad-access

Swift
1
star
53

tryCombine

tryCombine blog by Marin Todorov
HTML
1
star
54

Languages

RWDevCon tutorial code
Swift
1
star