• Stars
    star
    1,466
  • Rank 32,080 (Top 0.7 %)
  • Language
    Swift
  • License
    MIT License
  • Created almost 7 years ago
  • Updated about 3 years ago

Reviews

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

Repository Details

🕦 Modern Timer in Swift, Debouncer and Throttler (alternative to NSTimer) made with GCD

Repeat - modern NSTimer in GCD, debouncer and throttler

Version License Platform CocoaPods Compatible Carthage Compatible Twitter

★★ Star me to follow the project! ★★
Created by Daniele Margutti - danielemargutti.com

Repeat is small lightweight alternative to NSTimer with a modern Swift Syntax, no strong references, multiple observers reusable instances. Repeat is based upon GCD - Grand Central Dispatch. It also support debouncer and throttler features.

A deep look at Timers

If you want to learn more about it check out my article on Medium: "The secret world of NSTimer".

Features Highlights

Main features offered by Repeat are:

  • Simple, less verbose APIs methods to create and manage our timer. Just call every() or once to create a new Timer even in background thread.
  • Avoid strong references to the destination target and avoid NSObject inheritance.
  • Support multiple observers to receive fire events from timer.
  • Ability to pause , start , resume and reset our timer without allocating a new instance.
  • Ability to set different repeat modes (infinite : infinite sequence of fires, at regular intervals, finite : a finite sequence of fires, at regular intervals, once : a single fire events at specified interval since start).

Moreover Repeat also provide supports for:

  • Debouncer: Debouncer will delay a function call, and every time it's getting called it will delay the preceding call until the delay time is over.
  • Throttler: Throttling wraps a block of code with throttling logic, guaranteeing that an action will never be called more than once each specified interval.

Other Libraries You May Like

I'm also working on several other projects you may like. Take a look below:

Library Description
SwiftDate The best way to manage date/timezones in Swift
Hydra Write better async code: async/await & promises
Flow A new declarative approach to table managment. Forget datasource & delegates.
SwiftRichString Elegant & Painless NSAttributedString in Swift
SwiftLocation Efficient location manager
SwiftMsgPack Fast/efficient msgPack encoder/decoder

Documentation

Timer

Note: As any other object Repeater class is subject to the standard memory management rules. So once you create your timer instance you need to retain it somewhere in order to avoid premature deallocation just after the start command.

Create single fire timer

The following code create a timer which fires a single time after 5 seconds.

self.timer = Repeater.once(after: .seconds(5)) { timer in
  // do something	
}

Create recurrent finite timer

The following code create a recurrent timer: it will fire every 10 minutes for 5 times, then stops.

self.timer = Repeater.every(.minutes(10), count: 5) { timer  in
  // do something		
}

Create recurrent infinite timer

The following code create a recurrent timer which fires every hour until it is manually stopped .

self.timer = Repeater.every(.hours(1)) { timer in
  // do something
}

Manage a timer

You can create a new instance of timer and start as needed by calling the start() function.

self.timer = Repeater(interval: .seconds(5), mode: .infinite) { _ in
  // do something		
}
timer.start()

Other functions are:

  • start(): start a paused or newly created timer
  • pause(): pause a running timer
  • reset(_ interval: Interval, restart: Bool): reset a running timer, change the interval and restart again if set.
  • fire(): manually fire an event of the timer from an external source

Properties:

  • .id: unique identifier of the timer
  • .mode: define the type of timer (infinite,finite,once)
  • .remainingIterations: for a .finite mode it contains the remaining number of iterations before it finishes.

Adding/Removing Observers

By default a new timer has a single observer specified by the init functions. You can, however, create additional observer by using observe() function. The result of this call is a token identifier you can use to remove the observer in a second time. Timer instance received in callback is weak.

let token = timer.observe { _ in
  // a new observer is called		
}
timer.start()

You can remove an observer by using the token:

timer.remove(token)

Observing state change

Each timer can be in one of the following states, you can observe via .state property:

  • .paused: timer is in idle (never started yet) or paused
  • .running: timer is currently active and running
  • .executing: registered observers are being executed
  • .finished: timer lifecycle is finished (it's valid for a finite/once state timer)

You can listen for state change by assigning a function callback for .onStateChanged property.

timer.onStateChanged = { (timer,newState) in
	// your own code
}

Debouncer

Since 0.5 Repeater introduced Debouncer class. The Debouncer will delay a function call, and every time it's getting called it will delay the preceding call until the delay time is over.

The debounce function is an extremely useful tool that can help throttle requests. It is different to throttle though as throttle will allow only one request per time period, debounce will not fire immediately and wait the specified time period before firing the request. If there is another request made before the end of the time period then we restart the count. This can be extremely useful for calling functions that often get called and are only needed to run once after all the changes have been made.

let debouncer = Debouncer(.seconds(10))
debouncer.callback = {
	// your code here
}

// Call debouncer to start the callback after the delayed time.
// Multiple calls will ignore the older calls and overwrite the firing time.
debouncer.call()

(Make sure to check out the Unit Tests for further code samples.)

Throttler

Since 0.5 Repeater introduced Throttler class.

Throttling wraps a block of code with throttling logic, guaranteeing that an action will never be called more than once each specified interval. Only the last dispatched code-block will be executed when delay has passed.

let throttler = Throttler(time: .milliseconds(500), {
  // your code here
})

// Call throttler. Defined block will never be called more than once each specified interval.
throttler.call()

Requirements

Repeat is compatible with Swift 4.x. All Apple platforms are supported:

  • iOS 8.0+
  • macOS 10.10+
  • watchOS 2.0+
  • tvOS 9.0+

Latest Version

Latest version of Repeat is 0.5.4 published on 2018/04/28. Full changelog is available in CHANGELOG.md file.

Installation

Install via CocoaPods

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like Repeat in your projects. You can install it with the following command:

$ sudo gem install cocoapods

CocoaPods 1.0.1+ is required to build Repeat.

Install via Podfile

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

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'TargetName' do
use_frameworks!
pod 'Repeat'
end

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

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

github "malcommac/Repeat"

Run carthage to build the framework and drag the built Repeat.framework into your Xcode project.

More Repositories

1

SwiftDate

🐔 Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift.
Swift
7,603
star
2

SwiftLocation

⚓️ Async/Await CLLocationManager Wrapper for Apple Platforms
Swift
3,386
star
3

SwiftRichString

👩‍🎨 Elegant Attributed String composition in Swift sauce
Swift
3,097
star
4

Hydra

⚡️ Lightweight full-featured Promises, Async & Await Library in Swift
Swift
1,973
star
5

UIWindowTransitions

🏃‍♂️ Animated transitions for UIWindow's rootViewController property
Swift
472
star
6

ImageSizeFetcher

Finds the type/size of an image given its URL by fetching as little data as needed
Swift
440
star
7

ScrollStackController

🧩 Easy scrollable layouts in UIKit - an UIStackView which scroll and uses root views of child view controllers.
Swift
435
star
8

Owl

A declarative type-safe framework for building fast and flexible lists with UITableViews & UICollectionViews
Swift
432
star
9

Flow

Declarative approach to populate and manage UITableViews (see https://github.com/malcommac/FlowKit)
Swift
423
star
10

SwiftSimplify

🥷 High-performance polyline simplification library - port of simplify.js
Swift
299
star
11

DMLazyScrollView

Lazy Loading UIScrollView for iOS (with support for infinite scrolling)
Objective-C
293
star
12

DMPagerViewController

DMPagerViewController is page navigation controller like the one used in Twitter or Tinder
Objective-C
278
star
13

FlowKit

A declarative type-safe framework for building fast and flexible list with Tables & Collection
Swift
211
star
14

DMCircularScrollView

Infinite/Circular Scrolling Implementation for UIScrollView
Objective-C
205
star
15

ScrollingStackContainer

Efficient Scrolling UIStackView in Swift - DEPRECATED (use ScrollStackController)
Swift
198
star
16

SwiftScanner

String Scanner in pure Swift (supports unicode)
Swift
171
star
17

SwiftMsgPack

💬 Fast & Lightweight MsgPack Serializer & Deserializer for Swift
Swift
154
star
18

DMSlidingCell

Swipe To Reveal UITableViewCell Implementation as like in Twitter
Objective-C
152
star
19

DMSplitView

New NSSplitView class with multiple subviews resize behaviors and animated transitions
Objective-C
116
star
20

DMScrollingTicker

Advanced horizontal scrolling ticker for iOS
Objective-C
110
star
21

DMDynamicWaterfall

UICollectionView Waterfall Layout with UIKit Dynamics
Objective-C
109
star
22

DMTabBar

XCode 4.x like inspector segmented control
Objective-C
108
star
23

HermesNetwork

Swift
72
star
24

DMInspectorPalette

Animated NSScrollView with collapsible sections like in XCode Inspector
Objective-C
61
star
25

SwiftUnistroke

✍️ $1 Unistroke Gesture Recognizer in Swift
Swift
53
star
26

UAParserSwift

🗺 User-Agent Parser based upon ua-parser.js
Swift
40
star
27

DMPageControl

An high customizable alternative to UIPageControl
39
star
28

DMTwitterOAuth

Twitter OAuth Library (Callback URL Login)
Objective-C
37
star
29

DMScrollViewStack

DMScrollViewStack is a UIScrollView subclass that efficiently handles a vertical stack of multiple scrollviews
Objective-C
33
star
30

DMLocationManager

Location Manager for iOS made simple
Objective-C
27
star
31

DMPathBar

XCode's Yosemite like path bar of OS X
Objective-C
25
star
32

Swift-Coding-Guidelines

A repository to collect best practices when programming with Swift
21
star
33

xcbetarunner

Run & Debug projects [easily] with stable Xcode on beta iOS devices
Swift
17
star
34

GitLabSwift

🛵 Async/Await GitLab REST APIs v4 for Swift
Swift
17
star
35

DMCacheBox

Fast advanced caching system for Objective-C (Cocoa/iOS compatible)
Objective-C
14
star
36

RealEventsBus

🚎 Simple type-safe event bus implementation in swift
Swift
13
star
37

DMMultiDelegatesProxy

Multiple delegate architecture made using NSProxy
Objective-C
10
star
38

Glider-Old

✈️ Fast & powerful logger for Swift
Swift
9
star
39

NSSplitView-Animatable

NSSplitView Category to perform simple animations with dividers
Objective-C
9
star
40

SlidingSheet

Configurable Bottom Sheet for UIKit - like AirBnb and Apple Maps
Swift
8
star
41

CircularScroller

Efficient and Lightweight endless UIScrollView implementation in Swift
Swift
7
star
42

DMAPNServer

APN - Apple Push Notification Server in PHP
PHP
6
star
43

DMCoreDataUtils

Utilities methods for Apple's Core Data Storage
Objective-C
6
star
44

sentry-cocoa-sdk-xcframeworks

A mirror for https://github.com/getsentry/sentry-cocoa to add support for binary (xcframework) distribution with swift package manager.
Shell
4
star
45

CAKeyFrameAnimation-Evaluators

Easily specify CAKeyFrameAnimation curves using C functions or ObjC Class
Objective-C
3
star
46

ZoomableListController

Apple's iOS Weather App List Imitation written in Swift
Swift
2
star
47

MeetingBot

Your next call on Mac status bar
Swift
2
star
48

Konsole

In-app Swift tools for great iOS developers
1
star
49

DMGrid

A simple 2D Grid class made in Objective-C
Objective-C
1
star
50

Envy

Type safe environment variables from shell processes and .env files
1
star