Skip to content

Rocket Alert | User friendly, Modular and Modern iOS Alert View

License

Notifications You must be signed in to change notification settings

peppesapienza/RocketAlert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

96 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RocketAlert

Rockert Alert resolve the problem of being distracted by a boring AlertView with a user-friendly boarding process similar to a Chat Bot.

alt text alt text

Would you like to improve your User Experience's while asking user to do some action?

With a modern style and a powerful personalization RocketAlert will help you to increase your conversion rate.

Installation

CocoaPods

platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'RocketAlert', '1.0-beta.3'
end

Then, run the following command:

$ pod install

Communication

  • If you need help, use Stack Overflow. (Tag 'rocketalert')
  • If you find a bug or you have a feature request open an issue.
  • If you are an 🇮🇹 iOS Italian Developer follow us on Slack or Facebook Group
  • If you want to contribute, submit a pull request.

Usage

You can instantiate a Rocket by passing to its parameters a RocketAuthor and a RocketBlock object. After that, you can present the Rocket by performing the method show():

import RocketAlert

let author = RocketAuthor(image: yourUIImage, style: RocketImageStyle.round)
let textBlock = TextRocketBlock(text: "This is your first Block")
let rocket = Rocket(author: author, block: textBlock)

rocket.show()

You can destroy the alert by invoking the method dismiss() on the same rocket object:

rocket.dismiss()

RocketBlock

RocketBlock is a container of data and functionality and under the hood RocketBlock is nothing else than a simple UITableViewCell.

Depends on block type a user can interact with a block by Tap, Control Events (for example button click) and Input Events (at the moment only text input). After an event Rocket can show the next block that has been attached to the interacted block.

RocketBlock is a protocol that gives to all blocks a var id: String? {get set} property (created to be used in some advanced circumstances). There is also a var cellIdentifier: String {get} which is used internally to match the block with a reusable cell.

public protocol RocketBlock {
    var id: String? { get set }
    var cellIdentifier: String { get }
}

The RocketBlock protocol is never used as the base protocol of the implemented class. However, you will use the inherited protocols that give the blocks some useful stuff.

IMPORTANT: When a next block has been presented, the interaction over the previous block will be disabled.

TappableRocketBlock

The TappableRocketBlock is an inherited protocol of RocketBlock. The TappableRocketBlock protocol describes the block that can be tapped by the user. It gives to the implemented class two properties:

protocol TappableRocketBlock: RocketBlock {
    var next: RocketBlock? { get set }
    var showNextAfter: TimeInterval? { get set }
}
  1. The next property represent the next RocketBlock that will be shown after the tap.
  2. The showNextAfter property allows the next block, if presented, to be shown automatically after an amount of time. If you provide a value the TapGestureRecognizer will be disabled.

TextRocketBlock

You can use TextRocketBlock object to show a line or multiline string. The TextRocketBlock is an implemented class of the TappableRocketBlock protocol.

You can create a TextRocketBlock by using one of these init:

TextRocketBlock.init(text: String, next: RocketBlock, showNextAfter: TimeInterval? = nil)
TextRocketBlock.init(text: String, showNextAfter: TimeInterval)
TextRocketBlock.init(text: String, next: RocketBlock? = nil, showNextAfter: TimeInterval? = nil, id: String? = nil, font: RocketFont = .text)

And you can use it like that:

let secondBlock = TextRocketBlock(text: "This is your second block")
let firstBlock = TextRocketBlock(text: "This is your first block", next: secondBlock)
        
let rocket = Rocket(author: author, block: firstBlock)
rocket.show()

The secondBlock will be presented after the tap on the firstBlock. Pay attention that I passed the firstBlock to the rocket block parameter.

Flat style

Use this style when you have a lot of blocks and you want to maintain your code clear:

let firstBlock = TextRocketBlock(text: "First")
let secondBlock = TextRocketBlock(text: "Second")
let thirdBlock = TextRocketBlock(text: "Third")

firstBlock.next = second 

secondBlock.next = third
secondBlock.font = RocketFont.textBold

showNextAfter property

let firstBlock = TextRocketBlock(text: "First")
let secondBlock = TextRocketBlock(text: "Second")

firstBlock.next = second 
firstBlock.showNextAfter = 2.0

secondBlock.font = RocketFont.textBold

The thirdBlock will be shown automatically after 2.0 seconds and after the secondBlock.

Screenshot

RocketFont

You can change the UIFont by providing a RocketFont object to the font property.

let firstBlock = TextRocketBlock(text: "First", next: secondBlock)
firstBlock.font = RocketFont(font: UIFont, color: UIColor)
// or 
firstBlock.font = RocketFont.text // the default

The RocketFont provide some default styles:

block.font = RocketFont.emoji
block.font = RocketFont.text
block.font = RocketFont.textBold
block.font = RocketFont.button
block.font = RocketFont.lightButton
block.font = RocketFont.cancel

ImageRocketBlock

You can use ImageRocketBlock object to show an Image with or without text. The ImageRocketBlock is a subclass of the TextRocketBlock one, so you can edit the same properties.

You can instatiate an ImageRocketBlock by using one of these init:

ImageRocketBlock.init(image: UIImage, text: String?)
ImageRocketBlock.init(image: UIImage, text: String?, next: RocketBlock?, showNextAfter: TimeInterval?, id: String?)

You can add a padding to the internal ImageView by changing the properties paddingLeft and paddingRight. The default padding value is 0:

imageBlock.paddingLeft = 10
imageBlock.paddingRight = 10 

And you can round the corners of the ImageView by assigning a RocketImageStyle to the imageStyle property. The default value is .square:

imageBlock.imageStyle = .circular
imageBlock.imageStyle = .round
imageBlock.imageStyle = .square

Screenshot

ControlRocketBlock

The ControlRocketBlock is an inherited protocol of RocketBlock. The ControlRocketBlock protocol describes the interactable blocks.

ButtonRocketBlock

Use ButtonRocketBlock object to show a single button. Inside the init you won't be able to define a next block directly. However, you'll need to provide a TapRocketHandler object which will let you define a custom action and the next block (it will be fired after the TouchUpInside event).

You can create a ButtonRocketBlock using one of these init:

ButtonRocketBlock.init(title: String, tapHandler: TapRocketHandler) 
ButtonRocketBlock.init(title: String, tapHandler: TapRocketHandler, font: RocketFont)
ButtonRocketBlock.init(title: String, tapHandler: TapRocketHandler? = nil, font: RocketFont? = RocketFont.button, id: String? = nil)

The default RocketFont is .button.

TapRocketHandler

let button = ButtonRocketBlock(title: "PRESS HERE")
let afterTheTapOnButton = TextRocketBlock(text: "You press the button!!")

button.tapHandler = TapRocketHandler(next: afterTheTapOnButton, action: {
    print("the user click the button")
    
    UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        
    }
})

let rocket = Rocket(author: author, block: button)
rocket.show()

DoubleButtonRocketBlock

Use the DoubleButtonRocketBlock whenever you want to show two options. You can initialize a DoubleButtonRocketBlock passing to its init two ButtonRocketBlock. It's important to know that the touch over the block will be disabled when a user taps to one of the buttons.

let leftButton = ButtonRocketBlock(title: "Left Button")
leftButton.font = .button // the default

let rightButton = ButtonRocketBlock(title: "Right Button")
rightButton.font = .lightButton
rightButton.tapHandler = // remember to set a tapHandler if you want to show a block or if you want perform an action

let doubleButton = DoubleButtonRocketBlock(left: leftButton, right: rightButton)

InputRocketBlock

The InputRocketBlock is an inherited protocol of RocketBlock. The InputRocketBlock protocol describes the block that has an input field. It gives to the implemented class an InputRocketHandler<InputType> properties:

protocol InputRocketBlock: RocketBlock {
    associatedtype InputType
    var handler: InputRocketHandler<InputType>? { get set }
}

When you create an InputRocketHandler<T> you need to define a closure that returns back at least one RocketBlock:

public struct InputRocketHandler<T> {
    public init(action: ((T)->(RocketBlock?))?) {
        self.action = action
    }
    
    internal let action: ((_ text: T)->(RocketBlock?))?
}

TextInputRocketBlock

Use the TextInputRocketBlock whenever you want to ask the user to enter some String information. The TextInputRocketBlock is an implemented class of the InputRocketBlock protocol.

You can create a TextInputRocketBlock by using one of these init:

TextInputRocketBlock.init(text: String, buttonTitle: String)
TextInputRocketBlock.init(text: String, buttonTitle: String, inputHandler: InputRocketHandler<String>?)
TextInputRocketBlock.init(text: String, buttonTitle: String, inputHandler: InputRocketHandler<String>?, id: String? = nil, font: RocketFont? = RocketFont.text, buttonStyle: RocketFont? = RocketFont.lightButton)

This is an easy way you can use it:

let input = TextInputRocketBlock(text: "Describe your problem:", buttonTitle: "Send")

input.handler = InputRocketHandler<String>(action: { (input) -> RocketBlock? in
    return TextRocketBlock(text: "Thanks you so much!")
})

Return different blocks

If you want to handle the user's input in a different way, you can return a block based on the value of the InputRocketHandler:

let input = TextInputRocketBlock(text: "Describe your problem:", buttonTitle: "Send")

input.handler = InputRocketHandler<String>(action: { (input) -> RocketBlock? in
    if (input.isEmpty) {
        return TextRocketBlock(text: "Why haven't added a text? :(")
    }
    
    if (input == "SecretKey") {
        return TextRocketBlock(text: "Awesome!! you know the secret key")
    }
    
    let block = TextRocketBlock(text: "Thanks you so much!")
    /* you can concatenate more blocks if you want */
    return block
})

NotificationCenter

rocketBlockAddedEvent

You can subscribe your objects at Notification.Name.rocketBlockAddedEvent. to perform some custom actions. This event will be fired after a block is displayed on the screen.

The userInfo will bring with itself the index and the block presented.

// subscribe to the Notification.Name.rocketBlockAddedEvent
NotificationCenter
    .default
    .addObserver(self,
                 selector: #selector(ViewController.handleRocketAlertBlock),
                 name: Notification.Name.rocketBlockAddedEvent,
                 object: nil)
                    
                    
// handle the notification
@objc func handleRocketAlertBlock(_ sender: Notification) {
    guard
        let index = sender.userInfo?["index"] as? Int,
        let block = sender.userInfo?["block"] as? RocketBlock
    else { return }
    
    print(index, block)
}

rocketDismissEvent

rocketDismissEvent will be fired when rocket is dismissed (after the last block or after clicking to the close button). Inside the userInfo you will find the count of all blocks displayed and the blocks array:

NotificationCenter
    .default
    .addObserver(self,
                 selector: #selector(ViewController.handleRocketAlertBlock),
                 name: Notification.Name.rocketDismissEvent,
                 object: nil)
     

@objc func handleRocketDismissEvent(_ sender: Notification) {
    guard
        let count = sender.userInfo?["count"] as? Int,
        let blocks = sender.userInfo?["blocks"] as? [RocketBlock]
        else { return }
    
    print(count, blocks)
}

About

Rocket Alert | User friendly, Modular and Modern iOS Alert View

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published