All Projects → pawurb → WaitForIt

pawurb / WaitForIt

Licence: MIT license
Events and time based iOS app scenarios made easy.

Programming Languages

swift
15916 projects
ruby
36898 projects - #4 most used programming language
objective c
16641 projects - #2 most used programming language

Projects that are alternatives of or similar to WaitForIt

Android-Kotlin-Fundamentals
Bu repositorie Google'ın tamamıyla ücretsiz olarak sunduğu Android Kotlin Fundamentals dokümantasyonunun Türkçeye çevrilmiş halidir.
Stars: ✭ 277 (+965.38%)
Mutual labels:  mobile-development
react-native-slider-intro
A simple and fully customizable React Native component that implements an intro slider for your app
Stars: ✭ 80 (+207.69%)
Mutual labels:  mobile-development
KaiUI
Useful native UI components for KaiOS
Stars: ✭ 29 (+11.54%)
Mutual labels:  mobile-development
CrossMobile
Create native iOS, Android, Windows Phone and Desktop applications in Java. Write it once, and produce sophisticated multiplatform applications.
Stars: ✭ 48 (+84.62%)
Mutual labels:  mobile-development
18app
Official mobile app for 18app
Stars: ✭ 32 (+23.08%)
Mutual labels:  mobile-development
react-native-appsync-s3
React Native app for image uploads to S3 and storing their records in Amazon DynamoDB using AWS Amplify and AppSync SDK
Stars: ✭ 18 (-30.77%)
Mutual labels:  mobile-development
random-users-details
Random Users details in flutter from randomusers api
Stars: ✭ 14 (-46.15%)
Mutual labels:  mobile-development
android-sdk
AppSpector is a debugging service for mobile apps
Stars: ✭ 39 (+50%)
Mutual labels:  mobile-development
Prototype.Forms.Controls
This sample app contains a random mixture of Xamarin/Xamarin.Forms controls, views, and functionality snippets that I've created.
Stars: ✭ 21 (-19.23%)
Mutual labels:  mobile-development
FluentERP
ERP mobile application for Android with a support for SAP-like T-codes!
Stars: ✭ 18 (-30.77%)
Mutual labels:  mobile-development
CircularDialogs
Android dialog library to give user feedback about the common operations like Success, Warning and Errors.
Stars: ✭ 35 (+34.62%)
Mutual labels:  mobile-development
Generation
⭐ A Private, Secure, End-to-End Encrypted Messaging app made in Flutter(With Firebase and SQLite) that helps you to connect with your connections without any Ads, promotion. No other third-party person, organization, or even Generation Team can't read your messages. 💝
Stars: ✭ 18 (-30.77%)
Mutual labels:  mobile-development
AmazonSpeechTranslator
End-to-end Solution for Speech Recognition, Text Translation, and Text-to-Speech for iOS using Amazon Translate and Amazon Polly as AWS Machine Learning managed services.
Stars: ✭ 50 (+92.31%)
Mutual labels:  mobile-development
resources
A curated collection of useful tech resources 💻
Stars: ✭ 57 (+119.23%)
Mutual labels:  mobile-development
Manji
Manji is a mobile application built to help people learning Japanese learn about Kanji.
Stars: ✭ 142 (+446.15%)
Mutual labels:  mobile-development
data examples
An example app showing different ways to pass to and share data with widgets and pages.
Stars: ✭ 56 (+115.38%)
Mutual labels:  mobile-development
react-native-tab-bars
Fully customizable navigation tab bar for React Native
Stars: ✭ 16 (-38.46%)
Mutual labels:  mobile-development
react-native-passmeter
Simple password strength meter for React Native.
Stars: ✭ 46 (+76.92%)
Mutual labels:  mobile-development
react-native-ifood-clone
Repository with iFood clone (views) using React Native and styled-components.
Stars: ✭ 37 (+42.31%)
Mutual labels:  mobile-development
app-intro-lottie-expo
App Intro component with Expo, styled-components and Lottie
Stars: ✭ 46 (+76.92%)
Mutual labels:  mobile-development

WaitForIt Build Status Pod version Carthage compatible

WaitForIt makes implementing a common iOS app scenarios a breeze:

  • "Display a tutorial screen only when user launches an app for the first time."
  • "Ask user for a review, but only if he installed the app more then two weeks ago and launched it at least 5 times."
  • "Ask registered user to buy a subscription once every 3 days, but no more then 5 times in total."
  • "Ask user to share some content on Facebook, if he did not do it since 4 days."

Dealing with this kind of logic usually involves manually saving data to UserDefaults and has to be redone from scratch for each scenario.

Usage

WaitForIt provides a simple declarative API allowing you to handle most of the possible scenarios without worrying about underlaying implementation.

ScenarioProtocol has the following properties which can be used to define when a scenario should be executed:

protocol ScenarioProtocol {
    // minimum number of scenario events needed to be trigerred before scenario can be executed
    static var minEventsRequired: Int? { get set }

    // maximum number of scenario events which can be trigerred before scenario stops executing
    static var maxEventsPermitted: Int? { get set }

    // maximum number of times that scenario can be executed
    static var maxExecutionsPermitted: Int? { get set }

    // minimum time interval, after the first scenario event was trigerred, before the scenario can be executed
    static var minSecondsSinceFirstEvent: TimeInterval? { get set }

    // minimum time interval, after the last scenario event was trigerred, before the scenario can be executed
    static var minSecondsSinceLastEvent: TimeInterval? { get set }

    // minimum time interval before scenario can be executed again after previous execution
    static var minSecondsBetweenExecutions: TimeInterval? { get set }

    // custom conditions closure
    static var customConditions: (() -> Bool)? { get set }
}

Scenario is a simple struct which implements a single config function. You use it to configure values determining when a given scenario will execute.

You can operate on a scenario struct using static methods:

    // increment scenario specific event counter
    static func triggerEvent()

    // try to execute a scenario (it counts as executed only if bool param passed into a block was `true`)
    static func tryToExecute(completion: @escaping (Bool) -> Void)

    // reset scenario event and execution counters
    static func reset()

Basic example

Let's say you want to display a tutorial screen only once:

import WaitForIt

struct ShowTutorial: ScenarioProtocol {
    static func config() {
        maxExecutionsPermitted = 1
    }
}

// In ViewController.swift
func viewDidLoad() {
    super.viewDidLoad()
    ShowTutorial.tryToExecute { didExecute in
        if didExecute {
            self.showTutorial()
        }
    }
}

That's it! You no longer need to deal with UserDefaults yourself. Just configure a struct with correct execution conditions, and lib takes care of the rest. When all the conditions for your scenario are fulfilled, bool value passed inside the tryToExecute block will be true.

More conditions

Let's try a bit more complex scenario. You want to ask user to buy a subscription, if he installed an app at least 1 week ago and turned it on at least 5 times. You want to ask him once every 2 days but no more then 4 times in total:

import WaitForIt

struct AskToSubscribe: ScenarioProtocol {
    static func config() {
        minEventsRequired = 5
        minSecondsSinceFirstEvent = 604 800 // seconds in one week
        maxExecutionsPermitted = 4
        minSecondsBetweenExecutions = 172 800 // seconds in two days
    }
}

// In AppDelegate.swift
func application(_ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    AskToSubscribe.triggerEvent()
    AskToSubscribe.tryToExecute { didExecute in
        if didExecute {
            self.askToSubscribe()
        }
    }

    return true
}

Custom conditions

If time and event count based conditions are not enough for your scenario you can also define a custom conditions closure. It will be evaluated every time you try to execute a scenario:

struct ShowLowBrightnessAlertOnce: ScenarioProtocol {
    static func config() {
        customConditions = {
            return UIScreen.main.brightness < 0.3
        }
        maxExecutionsPermitted = 1
    }
}

Even more complex stories could be implemented if you decided to mix conditions from more then one scenario struct. Of course you could also scatter event triggers and scenario executions throughout the app, they don't need to be in the same file.

Implementation is based upon standard UserDefaults so data will not persist if app is reinstalled. UserDefaults key names are generated with struct names, so renaming the struct will reset all its data. You can also reset persisted data using reset() method.

Installation

Carthage

In your Cartfile:

github "pawurb/WaitForIt" ~> 2.0.0

Cocoapods

In your Podfile:

platform :ios, '10.0'
use_frameworks!

target 'TargetName' do
  pod 'WaitForIt'
end

Status

Lib is used in production but it is still in an early stage of development. Suggestions on how it could be improved are welcome.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].