An extensible monitoring framework written in Swift

Overview

XestiMonitors

Swift 4.x License Platform

Build Status Code Coverage Documented

CocoaPods Carthage Swift Package Manager

Overview

The XestiMonitors framework provides more than sixty fully-functional monitor classes right out of the box that make it easy for your app to detect and respond to many common system-generated events.

Among other things, you can think of XestiMonitors as a better way to manage the most common notifications (primarily on iOS and tvOS). At present, XestiMonitors provides “wrappers” around nearly all UIKit notifications (see UIKit Monitors) and many Foundation notifications (see Foundation Monitors).

XestiMonitors also provides convenient “wrappers” around several frameworks and programming interfaces to make them easier for your app to use:

  • It wraps the Core Location framework to make it easier for your app to make easier for your app to determine the device’s geographic location, altitude, or orientation; or its position relative to a nearby iBeacon. See Core Location Monitors for details.
  • It wraps the Core Motion framework to make it easier for your app to obtain both raw and processed motion measurements from the device. See Core Motion Monitors for details.
  • It wraps the SCNetworkReachability programming interface to make it super easy for your app to determine the reachability of a target host. See Other Monitors for details.

Additional monitors targeting more parts of all four platforms will be rolled out in future releases of XestiMonitors!

Finally, XestiMonitors is extensible—you can easily create your own custom monitors. See Custom Monitors for details.

Reference Documentation

Full reference documentation is available courtesy of Jazzy.

Requirements

  • iOS 9.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 9.0+
  • Swift 4.0+

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

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

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

target '<Your Target Name>' do
    pod 'XestiMonitors'
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 commands:

$ brew update
$ brew install carthage

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

github "eBardX/XestiMonitors"

Then, run the following command:

$ carthage update

Finally, drag the built XestiMonitors.framework into your Xcode project.

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler. It is in early development, but XestiMonitors does support its use on supported platforms.

Once you have your Swift package set up, adding XestiMonitors as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .Package(url: "https://github.com/eBardX/XestiMonitors.git")
]

Usage

All monitor classes conform to the Monitor protocol, thus enabling you to create arrays of monitors that can be started or stopped uniformly—fewer lines of code!

For example, in a view controller, you can lazily instantiate several monitors and, in addition, lazily instantiate an array variable containing these monitors:

import XestiMonitors

lazy var keyboardMonitor = KeyboardMonitor { [unowned self] in
    // do something…
}
lazy var memoryMonitor = MemoryMonitor { [unowned self] in
    // do something…
}
lazy var orientationMonitor = OrientationMonitor { [unowned self] in
    // do something…
}
lazy var monitors: [Monitor] = [keyboardMonitor,
                                memoryMonitor,
                                orientationMonitor]

Then, in the viewWillAppear(_:) and viewWillDisappear(_:) methods, you can simply start or stop all these monitors with a single line of code:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    monitors.forEach { $0.startMonitoring() }
}

override func viewWillDisappear(_ animated: Bool) {
    monitors.forEach { $0.stopMonitoring() }
    super.viewWillDisappear(animated)
}

Easy peasy!

Core Location Monitors

XestiMonitors provides seven monitor classes wrapping the Core Location framework that you can use to determine the device’s geographic location, altitude, or orientation; or its position relative to a nearby iBeacon:

  • BeaconRangingMonitor to monitor a region for changes to the ranges (i.e., the relative proximity) to the Bluetooth low-energy beacons within. (iOS)
  • HeadingMonitor to monitor the device for changes to its current heading. (iOS)
  • LocationAuthorizationMonitor to monitor the app for updates to its authorization to use location services. (iOS, macOS, tvOS, watchOS)
  • RegionMonitor to monitor a region for changes to its state (which indicate boundary transitions). (iOS, macOS)
  • SignificantLocationMonitor to monitor the device for significant changes to its current location. (iOS, macOS)
  • StandardLocationMonitor to monitor the device for changes to its current location. (iOS, macOS, tvOS, watchOS)
  • VisitMonitor to monitor for locations that the user stops at for a “noteworthy” amount of time. (iOS)

Core Motion Monitors

XestiMonitors provides seven monitor classes wrapping the Core Motion framework that you can use to obtain raw and processed motion measurements from the device:

  • AccelerometerMonitor to monitor the device’s accelerometer for periodic raw measurements of the acceleration along the three spatial axes. (iOS, watchOS)
  • AltimeterMonitor to monitor the device for changes in relative altitude. (iOS, watchOS)
  • DeviceMotionMonitor to monitor the device’s accelerometer, gyroscope, and magnetometer for periodic raw measurements which are processed into device motion measurements. (iOS, watchOS)
  • GyroscopeMonitor to monitor the device’s gyroscope for periodic raw measurements of the rotation rate around the three spatial axes. (iOS, watchOS)
  • MagnetometerMonitor to monitor the device’s magnetometer for periodic raw measurements of the magnetic field around the three spatial axes. (iOS, watchOS)
  • MotionActivityMonitor to monitor the device for live and historic motion data. (iOS, watchOS)
  • PedometerMonitor to monitor the device for live and historic walking data. (iOS, watchOS)

Foundation Monitors

XestiMonitors provides seventeen monitors wrapping Foundation notifications:

  • BundleClassLoadMonitor to monitor a bundle for dynamic loads of classes. (iOS, macOS, tvOS, watchOS)
  • BundleResourceRequestMonitor to monitor the system to detect if the amount of available disk space for on-demand resources is getting low. (iOS, tvOS, watchOS)
  • CalendarDayMonitor to monitor the system for changes to the calendar day. (iOS, macOS, tvOS, watchOS)
  • CurrentLocaleMonitor to monitor the system for changes to the user’s locale. (iOS, macOS, tvOS, watchOS)
  • ExtensionHostMonitor to monitor an extension context for changes to the runtime state of the extension’s host app. (iOS, tvOS, watchOS)
  • [HTTPCookiesStorageMonitor][http_cookies_storage_monitor] instance to monitor an HTTP cookie storage object for changes to its acceptance policy or to its cookies. (iOS, macOS, tvOS, watchOS)
  • MetadataQueryMonitor to monitor a metadata query for changes to its results. (iOS, macOS, tvOS, watchOS)
  • PortMonitor to monitor a port for changes to its validity. (iOS, macOS, tvOS, watchOS)
  • ProcessInfoPowerStateMonitor to monitor the device for changes to its power state (Low Power Mode is enabled or disabled). (iOS, tvOS, watchOS)
  • ProcessInfoThermalStateMonitor to monitor the system for changes to the thermal state. (iOS, macOS, tvOS, watchOS)
  • SystemClockMonitor to monitor the system for changes to the clock. (iOS, macOS, tvOS, watchOS)
  • SystemTimeZoneMonitor to monitor the system for changes to the currently used time zone. (iOS, macOS, tvOS, watchOS)
  • UbiquitousKeyValueStoreMonitor to monitor the iCloud (“ubiquitous”) key-value store for changes due to incoming data pushed from iCloud. (iOS, macOS, tvOS)
  • UbiquityIdentityMonitor to monitor the system for changes to the iCloud (”ubiquity”) identity. (iOS, macOS, tvOS, watchOS)
  • UndoManagerMonitor to monitor an undo manager for changes to its recording of operations. (iOS, macOS, tvOS, watchOS)
  • URLCredentialStorageMonitor to monitor the shared URL credential storage object for changes to its stored credentials. (iOS, macOS, tvOS, watchOS)
  • UserDefaultsMonitor to monitor a user defaults object for changes to its data. (iOS, macOS, tvOS, watchOS)

UIKit Monitors

XestiMonitors provides numerous monitors wrapping UIKit notifications.

Accessibility Monitors

XestiMonitors provides three monitor classes that you can use to observe accessibility events generated by the system:

Application Monitors

XestiMonitors provides seven monitor classes that you can use to observe common events generated by the system about the app:

  • ApplicationStateMonitor to monitor the app for changes to its runtime state. (iOS, tvOS)
  • BackgroundRefreshMonitor to monitor the app for changes to its status for downloading content in the background. (iOS)
  • MemoryMonitor to monitor the app for memory warnings from the operating system. (iOS, tvOS)
  • ProtectedDataMonitor to monitor the app for changes to the accessibility of protected files. (iOS, tvOS)
  • ScreenshotMonitor to monitor the app for screenshots. (iOS, tvOS)
  • StatusBarMonitor to monitor the app for changes to the orientation of its user interface or to the frame of the status bar. (iOS)
  • TimeMonitor to monitor the app for significant changes in time. (iOS, tvOS)

Device Monitors

XestiMonitors provides three monitor classes that you can use to detect changes in the characteristics of the device:

  • BatteryMonitor to monitor the device for changes to the charge state and charge level of its battery. (iOS)
  • OrientationMonitor to monitor the device for changes to its physical orientation. (iOS)
  • ProximityMonitor to monitor the device for changes to the state of its proximity sensor. (iOS)

Screen Monitors

XestiMonitors provides four monitor classes that you can use to detect changes in the properties associated with a screen:

Text Monitors

XestiMonitors provides four monitor classes that you can use to detect changes in text input mode and content:

Other UIKit Monitors

In addition, XestiMonitors provides nine other UIKit monitors:

  • ContentSizeCategoryMonitor to monitor the app for changes to its preferred content size category. (iOS, tvOS)
  • DocumentStateMonitor to monitor a document for changes to its state. (iOS)
  • FocusMonitor to monitor the app for changes to the current focus in the view hierarchy. (iOS, tvOS)
  • KeyboardMonitor to monitor the keyboard for changes to its visibility or to its frame. (iOS)
  • MenuControllerMonitor to monitor the menu controller for changes to the visibility of the editing menu or to the frame of the editing menu. (iOS)
  • PasteboardMonitor to monitor a pasteboard for changes to its contents or for its removal from the app. (iOS)
  • TableViewSelectionMonitor to monitor a table view for changes to its selected row. (iOS, tvOS)
  • ViewControllerShowDetailTargetMonitor to monitor the app for changes to a split view controller’s display mode in the view hierarchy. (iOS, tvOS)
  • WindowMonitor to monitor a window for changes to its visibility or key status. (iOS, tvOS)

KeyboardMonitor is especially handy in removing lots of boilerplate code from your app. This is how keyboard monitoring is typically handled in a custom view controller:

func keyboardWillHide(_ notification: Notification) {
    let userInfo = notification.userInfo
    var animationDuration: TimeInterval = 0
    if let value = (userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue {
        animationDuration = value
    }
    constraint.constant = 0
    UIView.animate(withDuration: animationDuration) {
        self.view.layoutIfNeeded()
    }
}

func keyboardWillShow(_ notification: Notification) {
    let userInfo = notification.userInfo
    var animationDuration: TimeInterval = 0
    if let value = (userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue {
        animationDuration = value
    }
    var frameEnd = CGRect.zero
    if let value = (userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        frameEnd = value
    }
    constraint.constant = frameEnd.height
    UIView.animate(withDuration: animationDuration) {
        self.view.layoutIfNeeded()
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let nc = NotificationCenter.`default`
    nc.addObserver(self, selector: #selector(keyboardWillHide(_:)),
                   name: .UIKeyboardWillHide, object: nil)
    nc.addObserver(self, selector: #selector(keyboardWillShow(_:)),
                   name: .UIKeyboardWillShow, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.`default`.removeObserver(self)
    super.viewWillDisappear(animated)
}

And this is the XestiMonitors way using KeyboardMonitor:

import XestiMonitors

lazy var keyboardMonitor = KeyboardMonitor { [unowned self] event in
    guard let constraint = self?.constraint,
          let view = self?.view else { return }
    switch event {
    case let .willHide(info):
        constraint.constant = 0
        UIView.animate(withDuration: info.animationDuration) {
            view.layoutIfNeeded()
        }
    case let .willShow(info):
        constraint.constant = info.frameEnd.height
        UIView.animate(withDuration: info.animationDuration) {
            view.layoutIfNeeded()
        }
    default:
        break
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    keyboardMonitor.startMonitoring()
}

override func viewWillDisappear(_ animated: Bool) {
    keyboardMonitor.stopMonitoring()
    super.viewWillDisappear(animated)
}

What’s in your wallet?

Other Monitors

In addition, XestiMonitors provides two other monitors:

Custom Monitors

Best of all, the XestiMonitors framework provides several ways to create your own custom monitors quite easily.

Implementing the Monitor Protocol

You can create a new class, or extend an existing class, that conforms to the Monitor protocol. You need only implement the startMonitoring() and stopMonitoring() methods, as well as the isMonitoring property:

import XestiMonitors

extension MegaHoobieWatcher: Monitor {
    var isMonitoring: Bool { return watchingForHoobiesCount() > 0 }

    func startMonitoring() -> Bool {
        guard !isMonitoring else { return }
        beginWatchingForHoobies()
    }

    func stopMonitoring() -> Bool {
        guard isMonitoring else { return }
        endWatchingForHoobies()
    }
}

Note: The guard statements in both startMonitoring() and stopMonitoring() protect against starting or stopping the monitor if it is in the incorrect state. This is considered good coding practice.

Subclassing the BaseMonitor Class

Typically, you will want to create a subclass of BaseMonitor. The advantage of using this abstract base class is that the basic guard logic is taken care of for you. Specifically, the startMonitoring() method does not attempt to start the monitor if it is already active, and the stopMonitoring() method does not attempt to stop the monitor if it is not active. Instead of directly implementing the required protocol methods and properties, you need only override the configureMonitor() and cleanupMonitor() methods of this base class. In fact, you will not be able to override the startMonitoring() and stopMonitoring() methods or the isMonitoring property—they are declared final in BaseMonitor.

import XestiMonitors

class GigaHoobieMonitor: BaseMonitor {
    let handler: (Float) -> Void
    @objc let hoobie: GigaHoobie
    private var observation: NSKeyValueObservation?

    init(_ hoobie: GigaHoobie, handler: @escaping (Float) -> Void) {
        self.handler = handler
        self.hoobie = hoobie
    }

    override func configureMonitor() -> Bool {
        super.configureMonitor()
        observation = hoobie.observe(\.nefariousActivityLevel) { [unowned self] hoobie, _ in
            self.handler(hoobie.nefariousActivityLevel) }
    }

    override func cleanupMonitor() -> Bool {
        observation?.invalidate()
        observation = nil
        super.cleanupMonitor()
    }
}

Note: Be sure to invoke the superclass implementations of both configureMonitor() and cleanupMonitor().

Subclassing the BaseNotificationMonitor Class

If your custom monitor determines events by observing notifications, you should consider creating a subclass of BaseNotificationMonitor instead. In most cases you need only override the addNotificationObservers(_:) method. You can also override the removeNotificationObservers(_:) method if you require extra cleanup when the notification observers are removed upon stopping the monitor. Although this base class inherits from BaseMonitor, you will not be able to override the configureMonitor() and cleanupMonitor() methods—they are declared final in BaseNotificationMonitor.

import XestiMonitors

class TeraHoobieMonitor: BaseNotificationMonitor {
    let handler: (Bool) -> Void
    let hoobie: TeraHoobie

    init(hoobie: TeraHoobie, queue: OperationQueue = .main,
         handler: @escaping (Bool) -> Void) {
        self.handler = handler
        self.hoobie = hoobie
        super.init(queue: queue)
    }

    override func addNotificationObservers() -> Bool {
        super.addNotificationObservers()
        observe(.teraHoobieDidChange) { [unowned self] _ in
            self.handler(self.hoobie.value) }
    }
}

Note: Be sure to invoke the superclass implementations of both addNotificationObservers(_:) and removeNotificationObservers(_:) in your overrides.

Credits

J. G. Pusey ([email protected])

License

XestiMonitors is available under the MIT license.

Comments
  • Add user defaults monitor

    Add user defaults monitor

    What is the purpose of this pull request?

    Add User Defaults Monitor

    Background

    #44

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by Descartess 8
  • Add UserDefaultsMonitor

    Add UserDefaultsMonitor

    Feature Name

    • UserDefaultsMonitor -- should live in Foundation folder

    Events

    • didChange(UserDefaults) -- wraps UserDefaults.didChangeNotification notification
    • sizeLimitExceeded -- wraps UserDefaults.sizeLimitExceededNotification notification

    Platform

    iOS/macOS/tvOS/watchOS

    feature request 
    opened by eBardX 5
  • Add ContentSizeCategoryMonitor

    Add ContentSizeCategoryMonitor

    Feature Name

    • ContentSizeCategoryMonitor

    Events

    • didChange(UIContentSizeCategory) -- wraps UIContentSizeCategoryDidChange notification

    Platform

    • iOS/tvOS
    feature request 
    opened by Descartess 5
  • added url credential storage monitor

    added url credential storage monitor

    What is the purpose of this pull request?

    added url credential storage monitor

    Background

    https://github.com/eBardX/XestiMonitors/issues/50

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by angiemugo 3
  • Add extension host monitor

    Add extension host monitor

    What is the purpose of this pull request?

    Add extension host monitor.

    Background

    #48

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by rosemaina 3
  • Add UbiquitousUserDefaultsMonitor

    Add UbiquitousUserDefaultsMonitor

    Feature Name

    • UbiquitousUserDefaultsMonitor -- should live in Foundation folder

    Events

    • completedInitialCloudSync -- wraps UserDefaults.completedInitialCloudSyncNotification notification
    • didChangeCloudAccounts -- wraps UserDefaults.didChangeCloudAccountsNotification notification
    • noCloudAccount -- wraps UserDefaults.noCloudAccountNotification notification

    Platform

    iOS /tvOS/watchOS

    feature request 
    opened by Descartess 3
  • Add HTTPCookieStorageMonitor

    Add HTTPCookieStorageMonitor

    Feature Name

    • HTTPCookieStorageMonitor -- should live in Foundation folder

    Events

    • acceptPolicyChanged(HTTPCookieStorage) -- wraps NSHTTPCookieManagerAcceptPolicyChanged notification
    • cookiesChanged(HTTPCookieStorage) -- wraps NSHTTPCookieManagerCookiesChanged notification

    Note: Since there can be multiple instances of HTTPCookieStorage; HTTPCookieStorageMonitor should provide both a cookieStorage property and a cookieStorage initializer parameter.

    Platform

    iOS/macOS /tvOS/watchOS

    feature request 
    opened by eBardX 3
  • Added bundle resource request monitor

    Added bundle resource request monitor

    What is the purpose of this pull request?

    Adds BundleResourceRequestMonitor

    Background

    #58

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by eBardX 2
  • Add system time zone monitor

    Add system time zone monitor

    What is the purpose of this pull request?

    Adds system time zone monitor

    Background

    https://github.com/eBardX/XestiMonitors/issues/54

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [x] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [ ] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by angiemugo 2
  • Add URLCredentialStorageMonitor

    Add URLCredentialStorageMonitor

    Feature Name

    • URLCredentialStorageMonitor -- should live in Foundation folder

    Events

    • changed(URLCredentialStorage) -- wraps NSURLCredentialStorageChanged notification

    Platform

    iOS/macOS /tvOS/watchOS

    feature request 
    opened by eBardX 2
  • Implement Undo Manager Monitor

    Implement Undo Manager Monitor

    What is the purpose of this pull request?

    Add Undo Manager Monitor

    Background

    #41

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have documented all my changes.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests pass.
    opened by rosemaina 2
  • Add AVAudioSessionMonitor

    Add AVAudioSessionMonitor

    What is the purpose of this pull request?

    Adds AudioSessionMonitor

    Background

    #76

    Checklist

    • [ ] Bug fix (non-breaking change which fixes an issue).
    • [x] New feature (non-breaking change which adds functionality).
    • [ ] Breaking change (fix or feature that would cause existing functionality to change).
    • [x] I have read the CONTRIBUTING guidelines.
    • [x] My code follows the coding style of this project.
    • [x] My change requires a change to the documentation.
    • [ ] I have documented all my changes.
    • [ ] I have added tests to cover my changes.
    • [ ] All new and existing tests pass.
    WIP 
    opened by Descartess 0
  • Add AVAudioSession Monitor

    Add AVAudioSession Monitor

    AVAudioSessionMonitor

    AVAudioSession Monitor -- should live in the Other folder

    Events

    • didInterruptAudio wraps AVAudioSession.interruptionNotification
    • didChangeRoute wraps AVAudioSession.routeChangeNotification
    • didSilenceSecondaryAudioHint wraps AVAudioSession.silenceSecondaryAudioHintNotification
    • mediaServerDidTerminate wraps AVAudioSession.mediaServicesWereLostNotification
    • mediaServerDidRestart wraps AVAudioSession.mediaServicesWereResetNotification

    Platform

    iOS/tvOS/watchOS

    feature request 
    opened by Descartess 0
Owner
J. G. Pusey
Freelance iOS developer.
J. G. Pusey
Swift-HorizontalPickerView - Customizable horizontal picker view component written in Swift for UIKit/iOS

Horizontal Picker View Customizable horizontal picker view component written in

Afraz Siddiqui 8 Aug 1, 2022
A utility that reminds your iPhone app's users to review the app written in pure Swift.

SwiftRater SwiftRater is a class that you can drop into any iPhone app that will help remind your users to review your app on the App Store/in your ap

Takeshi Fujiki 289 Dec 12, 2022
A simple Pokedex app written in Swift that implements the PokeAPI, using Combine and data driven UI.

SwiftPokedex SwiftPokedex is a simple Pokedex app written by Viktor Gidlöf in Swift that implements the PokeAPI. For full documentation and implementa

Viktor G 26 Dec 14, 2022
noppefoxwolf/notion is a notion.so API library written in swift.

notion noppefoxwolf/notion is a notion.so API library written in swift. Installation Xcode Project > Swift Packages [email protected]:noppefoxwolf/notion

noppefoxwolf 44 Oct 7, 2022
Just another NES emulator written in Swift

SwiftNes This repo contains all the source code for my experimental 100 days of NES challenge. What is this all about? I'm planning to build a fully w

Tibor Bödecs 44 Dec 24, 2021
Python VM written in Swift

Violet Violet is one of those Swift <-> Python interop thingies, except that this time we implement the whole language from scratch. Name comes from V

LiarPrincess 157 Dec 14, 2022
A (slow) ray tracer written in Swift.

Blitzlichtgewitter Blitzlichtgewitter is a (slow) ray tracer written in Swift. It loosely follows the steps described in The Ray Tracer Challenge by J

Lennart Stolz 1 Dec 21, 2021
Readium Mobile is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin.

Readium Swift Toolkit Readium Mobile is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin. This toolkit is a modular project, whic

Readium 89 Dec 30, 2022
A simple, but efficient CSV Parser, written in Swift.

CSV CSV.swift is a powerful swift library for parsing CSV files that supports reading as [String], [String: String] and Decodable, without sacrificing

Ben Koska 4 Nov 28, 2022
Questrade API written in Swift

QuestradeAPI Getting Started The QuestAPI is made up of two main concepts: ResponseProviders API ResponseProviders The job of the provider is to retur

Eli Slade 2 Mar 15, 2022
A parser combinator library written in the Swift programming language.

SwiftParsec SwiftParsec is a Swift port of the Parsec parser combinator library. It allows the creation of sophisticated parsers from a set of simple

David Dufresne 219 Nov 6, 2022
Simple and Lightweight App Version Tracking for iOS written in Swift

AEAppVersion Simple and lightweight iOS App Version Tracking written in Swift I made this for personal use, but feel free to use it or contribute. For

Marko Tadić 12 Nov 11, 2022
Simple getter for bundle informations, written in Swift

BundleInfos Simple getter for bundle informations It's simple and static way for getting information from main bundle Requirements iOS 8.0+ Xcode 7.3

Jay Choi 1 Dec 3, 2017
Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX)

Mission Control Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX) Brought to you by Have you ever wished you could chang

appculture 113 Sep 9, 2022
SuggestionsBox helps you build better a product trough your user suggestions. Written in Swift. 🗳

SuggestionsBox An iOS library to aggregate users feedback about suggestions, features or comments in order to help you build a better product. Swift V

Manuel Escrig 100 Feb 6, 2022
FancyGradient is a UIView subclass which let's you animate gradients in your iOS app. It is purely written in Swift.

FancyGradient is a UIView subclass which let's you animate gradients in your iOS app. It is purely written in Swift. Quickstart Static gradient let fa

Derek Jones 11 Aug 25, 2022
Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.

Zip A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip. Usage Import Zip at the top of the Swift file

Roy Marmelstein 2.3k Jan 3, 2023
💻 A fast and flexible O(n) difference algorithm framework for Swift collection.

A fast and flexible O(n) difference algorithm framework for Swift collection. The algorithm is optimized based on the Paul Heckel's algorithm. Made wi

Ryo Aoyama 3.3k Jan 4, 2023
RandomKit is a Swift framework that makes random data generation simple and easy.

RandomKit is a Swift framework that makes random data generation simple and easy. Build Status Installation Compatibility Swift Package Manager CocoaP

Nikolai Vazquez 1.5k Dec 29, 2022