Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dalu93/Each

Elegant ⏱ interface for Swift apps
https://github.com/dalu93/Each

swift timer

Last synced: about 2 months ago
JSON representation

Elegant ⏱ interface for Swift apps

Awesome Lists containing this project

README

        

# Each
Elegant ⏱ interface for Swift apps

[![BuddyBuild](https://dashboard.buddybuild.com/api/statusImage?appID=5805caae4b74d00100717ec7&branch=master&build=latest)](https://dashboard.buddybuild.com/apps/5805caae4b74d00100717ec7/build/latest)

Each is a NSTimer bridge library written in Swift.

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [Leaks](#leaks)
- [License](#license)

## Features

- [x] Completely configurable timers
- [x] Support for time intervals in ms, seconds, minutes and hours
- [x] Fully extendable
- [x] More readable and simple to use in comparison with NSTimer object

## Requirements

- iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
- Xcode 8.0+
- Swift 3.0+

## Installation

### CocoaPods

[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:

```bash
$ gem install cocoapods
```

> CocoaPods 1.1.0+ is required to build Each.

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

```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '' do
pod 'Each', '~> 1.2'
end
```

Then, run the following command:

```bash
$ pod install
```

### Carthage

You can use [Carthage](https://github.com/Carthage/Carthage) to install `Each` by adding it to your `Cartfile`:

```
github "dalu93/Each"
```

## Usage

### Creating a new timer instance

```swift
let timer = Each(1).seconds // Can be .milliseconds, .seconds, .minute, .hours
```

### Performing operations

```swift
timer.perform {
// Do your operations
// This closure has to return a NextStep value
// Return .continue if you want to leave the timer active, otherwise
// return .stop to invalidate it
}
```

If you want to leave the memory management decision to the `Each` class, you can simply use the `perform(on: _)` method.
It requires that the parameter is an `AnyObject` instance.

```swift
timer.perform(on: self) {
// Do your operations
// This closure has to return a NextStep value
// Return .continue if you want to leave the timer active, otherwise
// return .stop to invalidate it
}
```

### Stopping the timer manually

```swift
timer.stop() // This stops immediately the timer
```

### Restarting the timer

You can restart the timer only after you stopped it. This method restarts the timer with the same
perform closure.

```swift
timer.restart()
```

## Leaks
Unfortunately the interface doesn't help you with handling the memory leaks the timer
could create. In case of them, two workarounds are provided

### Workaround 1

Use the `perform(on: _)` method as explained in the [usage](#usage) section.
Please note that using this method, the `timer` isn't immediately deallocated when the `owner` is deallocated.
It will be deallocated when the `timer` triggers the next time and it will check whether the `owner` instance is still valid or not.

### Workaround 2

In case you don't want to declare a property that holds the `Each` reference, create a normal `Each` timer in your method scope and return `.stop/true` whenever the `owner` instance is `nil`

```swift
Each(1).seconds.perform { [weak self] in
guard let _ = self else { return .stop }

print("timer called")
return .continue
}
```

90% of closures will call `self` somehow, so this isn't so bad

### Workaround 3

In case the first workaround wasn't enough, you can declare a property that holds the `Each` reference and call the `stop()` function whenever the `owner` is deallocated

```swift
final class ViewController: UIViewController {
private let _timer = Each(1).seconds

deinit {
_timer.stop()
}

override func viewDidLoad() {
super.viewDidLoad()
_timer.perform {
// do something and return. you can check here if the `self` instance is nil as for workaround #1
}
}
}
```

## License

Each is released under the MIT license. See LICENSE for details.