A very simple way to implement Backbone.js style custom event listeners and triggering in Swift for iOS development.

Overview

Swift Custom Events

A very simple way to implement Backbone.js style custom event listeners and triggering in Swift for iOS development.

This provides a convenient way to organize your code. It's especially useful for game systems like keeping track of events that count towards achievements.

Updated for Swift 3.

Usage

Custom event listeners allow us to separate our concerns and prevent function call spaghetti. We can keep the event agnostic while we add and remove functionality.

I prefer creating an 'Events' property of type EventManager on each Class you wish to track. Alternatively, you can also inherit this code onto any classes you like. Or, you can maintain one EventsManager object for your entire app (but listener performance may suffer with many listeners).

This system is a bit more simple and works differently than Backbone's (for one, they use JS prototypes to get their Event code onto all backbone objects). It's intended as a starting place for custom events in Swift.

Example

Let's create a cat class that can bug us while we're coding:

class Cat {
    let events = EventManager();
    
    func meow() {
        println("Cat: MRaawwweeee");
        self.events.trigger("meow", information: "The cat is hungry!");
    }
}

And a human class to represent ourselves:

class Human {
    func adoptCat(cat:Cat) {
        // you can pass in an anonymous code block to the event listener
        cat.events.listenTo("meow", action: {
            println("Human: Awww, what a cute kitty *pets cat*");
        });
        
        // or you can pass a function reference
        cat.events.listenTo("meow", action: self.dayDream);
        
        // Using the information from the trigger:
        // (notice the parameters for ponderCat)
        cat.events.listenTo("meow", action: self.ponderCat);
    }
    
    func dayDream() {
        println("Human daydreams about owning a dog");
    }
    
    func ponderCat(information:Any?) {
        if let info = information as? String {
            println("Oooh, I think I know:");
            println(info);
        }
    }
}

Play out our little scene:

let zeus = Cat();
let stephen = Human();

stephen.adoptCat(zeus);
zeus.meow();
/*
 * Cat: MRaawwweeee
 * Human: Awww, what a cute kitty *pets cat*
 * Human daydreams about owning a dog
 * Oooh, I think I know:
 * The cat is hungry!
*/

Disclosure:

This is potentially slower than using delegates or direct function calls (see performance testing, below). On the other hand, it's easier and faster to implement (especially in cases with multiple listeners per event).

This is a very early system developed for my specific needs. Feel free to use and adapt as you need, and please send any feedback or improvements.

Performance Testing:

I performed a real world comparison between using event triggers and a direct function call. On average, the event trigger took 0.23 milliseconds to get into the action code. Direct function calls performed in ~0.097 milliseconds. Phew, that's quick! More testing is needed, but I expected much worse results. Function calls are twice as fast, but event triggers using this code are still pretty quick!

Potential improvements/considerations:

  • I haven't tested what happens if you remove instances of either the listener or event object from memory after wiring up a listener.
  • Needs performance testing and tuning.
  • Ability to remove only a specific action from listener array.
You might also like...
The Gini Bank SDK provides components for capturing, reviewing and analyzing photos of invoices and remittance slips.
The Gini Bank SDK provides components for capturing, reviewing and analyzing photos of invoices and remittance slips.

Gini Bank SDK for iOS The Gini Bank SDK provides components for capturing, reviewing and analyzing photos of invoices and remittance slips. By integra

Alter SDK is a cross-platform SDK consisting of a real-time 3D avatar system, facial motion capture, and an Avatar Designer component built from scratch for web3 interoperability and the open metaverse.
Alter SDK is a cross-platform SDK consisting of a real-time 3D avatar system, facial motion capture, and an Avatar Designer component built from scratch for web3 interoperability and the open metaverse.

Alter SDK is a cross-platform SDK consisting of a real-time 3D avatar system, facial motion capture, and an Avatar Designer component built from scratch for web3 interoperability and the open metaverse.

Accept credit cards and PayPal in your iOS app
Accept credit cards and PayPal in your iOS app

Important: PayPal Mobile SDKs are Deprecated. The APIs powering them will remain operational long enough for merchants to migrate, but the SDKs themse

Unopinionated and flexible library for easily integrating Tumblr data into your iOS or OS X application.

Tumblr SDK for iOS An unopinionated and flexible library for easily integrating Tumblr data into your iOS or OS X application. The library uses ARC re

Build, Measure and Grow iOS subscription business

Apphud SDK Apphud SDK is a lightweight open-source Swift library to manage auto-renewable subscriptions and other in-app purchases in your iOS app. No

Sample app to demonstrate the integration code and working of Dyte SDK for iOS, using Objective-C.
Sample app to demonstrate the integration code and working of Dyte SDK for iOS, using Objective-C.

iOS sample app (using Objective-C) by dyte Sample app to demonstrate the usage of Dyte iOS SDK Explore the docs » View Demo · Report Bug · Request Fea

All in one eKYC (Electronic Know Your Customer) solution available for android and ios
All in one eKYC (Electronic Know Your Customer) solution available for android and ios

WideKYC All in one eKYC (Electronic Know Your Customer) solution available for android and ios. Wide Technologies provides an SDK for you to implement

A Flutter plugin to wrap HyperPay SDK for iOS and Android.
A Flutter plugin to wrap HyperPay SDK for iOS and Android.

HyperPay Flutter Plugin This plugin is a wrapper around HyperPay iOS and Android SDK, it's still in alpha release, and supports limited set of functio

A framework that enhances HealthKit and the Fitbit API for iOS
A framework that enhances HealthKit and the Fitbit API for iOS

VitoKit 😀 Welcome to VitoKit... A framework that enhances HealthKit and the Fitbit API for iOS ✅ Features Wonderfully crafted animations Speedy setup

Comments
  • [Any] is not a subtype of ()

    [Any] is not a subtype of ()

    Using Xcode 6.0.1, I got this error: [Any] is not a subtype of () with the simple code of

    cat.events.listenTo("meow", {
      println("Human: Awww, what a cute kitty *pets cat*");
    });
    

    or

    cat.events.listenTo("meow", self.dayDream);
    
    opened by remithomas 2
  • No work for me :(

    No work for me :(

    When I want to define a listener get this error,

    Argument labels '(_:, action:)' do not match any available overloads

    I'm new to swift and I do not know how to solve it

    opened by ezesoler 0
  • Pass information to listeners

    Pass information to listeners

    Doesn't look like information is being used at all: https://github.com/StephenHaney/Swift-Custom-Events/blob/master/Events.swift#L50

    Shouldn't this be passed to the listeners?

    opened by devth 0
Owner
Stephen Haney
Founder/CTO at Modulz
Stephen Haney
ESF modular ingestion tool for development and research.

ESFang This is a tool devised for modular consumption of EndpointSecurity Framework (ESF) events from the MacOs environment. This is my attempt to ove

F-Secure Countercept 17 Dec 5, 2022
Here it is my study note for iOS development.

iOS-Projects for beginners HI, this is Kaia and here it is my study note for iOS development. Check the detailed Notes below: Project Name Objective B

Qingying Gao(Kaia) 2 Nov 2, 2022
MainTask - Create main task by using a simple way

MainTask Create a main task by using a simple way. MainTask { print(Thread.c

Underthestars-zhy 1 Jan 17, 2022
Zilla connect is an easy, fast and secure way for your users to buy now and pay later from your app

Zilla Checkout iOS SDK Zilla connect is an easy, fast and secure way for your us

null 0 Jan 19, 2022
Smooch is the best way to have personal, rich conversations with people on your website or customers on any device

Smooch is the best way to have personal, rich conversations with people on your website or customers on any device. Our features, integrations and developer-friendly APIs empower companies to connect with their customers in a whole new way.

Zendesk 121 Aug 1, 2022
A simple to use iOS/tvOS/watchOS SDK to help get you off the ground quickly and efficiently with your Elastic Path Commerce Cloud written in Swift.

Elastic Path Commerce Cloud iOS Swift SDK A simple to use iOS/tvOS/watchOS SDK to help get you off the ground quickly and efficiently with your Elasti

Moltin 36 Aug 1, 2022
Simple proxy in Swift for converting between HTTP and API Gateway Lambda payloads

SwiftLambdaProxy A simple proxy that can convert HTTP requests to Lambda API Gat

Jānis Kiršteins 1 Jan 3, 2022
Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app.

Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app. With a few lines of code, you can connect your app with the Shopify platform and let your users buy your products using Apple Pay or their credit card.

Shopify 411 Jan 2, 2023
📲 The curated list of iOS Developer interview questions and answers, Swift & Objective-C

Awesome iOS interview questions and answers ?? Get started by picking interview's language and start preparing right now Install the app Prepare for t

Dasha Korneichuk 996 Dec 28, 2022
MbientLab 2 Feb 5, 2022