Commit 273ad08c authored by Aral Balkan's avatar Aral Balkan

Initial add.

parent c082eda7
.DS_Store
# Via https://github.com/github/gitignore/blob/master/Objective-C.gitignore
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
\ No newline at end of file
......@@ -12,6 +12,9 @@
A74BB46C1AE53419001CA7BB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A74BB46B1AE53419001CA7BB /* Images.xcassets */; };
A74BB46F1AE53419001CA7BB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A74BB46D1AE53419001CA7BB /* Main.storyboard */; };
A74BB47B1AE53419001CA7BB /* DelayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74BB47A1AE53419001CA7BB /* DelayTests.swift */; };
A74BB4851AE53434001CA7BB /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74BB4841AE53434001CA7BB /* Delay.swift */; };
A74BB48A1AE5388E001CA7BB /* Handle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74BB4881AE5388E001CA7BB /* Handle.swift */; };
A74BB48B1AE5388E001CA7BB /* NSNotificationCenterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74BB4891AE5388E001CA7BB /* NSNotificationCenterExtensions.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -34,6 +37,9 @@
A74BB4741AE53419001CA7BB /* DelayTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DelayTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A74BB4791AE53419001CA7BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A74BB47A1AE53419001CA7BB /* DelayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelayTests.swift; sourceTree = "<group>"; };
A74BB4841AE53434001CA7BB /* Delay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = "<group>"; };
A74BB4881AE5388E001CA7BB /* Handle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Handle.swift; sourceTree = "<group>"; };
A74BB4891AE5388E001CA7BB /* NSNotificationCenterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNotificationCenterExtensions.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -75,6 +81,8 @@
A74BB4641AE53419001CA7BB /* Delay */ = {
isa = PBXGroup;
children = (
A74BB4861AE53866001CA7BB /* Libraries */,
A74BB4841AE53434001CA7BB /* Delay.swift */,
A74BB4671AE53419001CA7BB /* AppDelegate.swift */,
A74BB4691AE53419001CA7BB /* ViewController.swift */,
A74BB46B1AE53419001CA7BB /* Images.xcassets */,
......@@ -109,6 +117,23 @@
name = "Supporting Files";
sourceTree = "<group>";
};
A74BB4861AE53866001CA7BB /* Libraries */ = {
isa = PBXGroup;
children = (
A74BB4871AE5387B001CA7BB /* Handle */,
);
name = Libraries;
sourceTree = "<group>";
};
A74BB4871AE5387B001CA7BB /* Handle */ = {
isa = PBXGroup;
children = (
A74BB4881AE5388E001CA7BB /* Handle.swift */,
A74BB4891AE5388E001CA7BB /* NSNotificationCenterExtensions.swift */,
);
name = Handle;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
......@@ -208,8 +233,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A74BB4851AE53434001CA7BB /* Delay.swift in Sources */,
A74BB46A1AE53419001CA7BB /* ViewController.swift in Sources */,
A74BB48B1AE5388E001CA7BB /* NSNotificationCenterExtensions.swift in Sources */,
A74BB4681AE53419001CA7BB /* AppDelegate.swift in Sources */,
A74BB48A1AE5388E001CA7BB /* Handle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="6198" systemVersion="14A297b" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="7531" systemVersion="14D131" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6198"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7531"/>
</dependencies>
<scenes>
<!--Application-->
......@@ -641,16 +641,16 @@
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="target"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Delay" customModuleProvider="target"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
<!--Window Controller - Window-->
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<window key="window" title="Delay" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
......@@ -667,15 +667,145 @@
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="Delay" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<rect key="frame" x="0.0" y="0.0" width="480" height="236"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cSB-JX-5mZ">
<rect key="frame" x="14" y="155" width="81" height="32"/>
<buttonCell key="cell" type="push" title="3 secs" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="xgk-SF-BhX">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="threeSecondsButtonAction:" target="XfG-lQ-9wD" id="s2N-85-2J1"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jlc-qY-t9o">
<rect key="frame" x="108" y="155" width="81" height="32"/>
<buttonCell key="cell" type="push" title="5 secs" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AfS-v7-2Lp">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="fiveSecondsButtonAction:" target="XfG-lQ-9wD" id="yZd-yT-0wq"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D8O-EX-Wz2">
<rect key="frame" x="108" y="122" width="83" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Mcb-eV-MZo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelFiveSecondDelayButtonAction:" target="XfG-lQ-9wD" id="u0Y-lt-ZJ2"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XoN-Av-y9P">
<rect key="frame" x="20" y="93" width="72" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="Vyp-mu-kxK">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E7d-SD-zlU">
<rect key="frame" x="18" y="199" width="72" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Simple" id="sUi-Dg-hW4">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aj5-aC-ht9">
<rect key="frame" x="110" y="199" width="81" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Cancellable" id="28W-sG-GEe">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F9h-Gs-DqK">
<rect key="frame" x="114" y="93" width="72" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="URQ-e0-vTl">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JaS-iE-rER">
<rect key="frame" x="221" y="163" width="239" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="Pbd-X7-bEF">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DXu-v1-VJk">
<rect key="frame" x="220" y="20" width="240" height="135"/>
<clipView key="contentView" id="K86-K3-pQn">
<rect key="frame" x="1" y="1" width="223" height="133"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" smartInsertDelete="YES" id="y8E-i6-n2k">
<rect key="frame" x="0.0" y="0.0" width="223" height="133"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="238" height="133"/>
<size key="maxSize" width="463" height="10000000"/>
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="238" height="133"/>
<size key="maxSize" width="463" height="10000000"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<constraints>
<constraint firstAttribute="height" constant="135" id="Lnb-Nk-ITP"/>
<constraint firstAttribute="width" constant="240" id="Vcq-cE-od8"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="PPx-1n-L2D">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="YQk-Qe-vWf">
<rect key="frame" x="224" y="1" width="15" height="133"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="scO-46-h7T">
<rect key="frame" x="219" y="199" width="64" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Throttled" id="Ge5-h0-s6e">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="DXu-v1-VJk" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" constant="220" id="c7B-pB-P6k"/>
<constraint firstAttribute="trailing" secondItem="DXu-v1-VJk" secondAttribute="trailing" constant="20" id="eLF-sQ-DMp"/>
<constraint firstItem="DXu-v1-VJk" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="81" id="hsc-Mf-dD2"/>
<constraint firstAttribute="bottom" secondItem="DXu-v1-VJk" secondAttribute="bottom" constant="20" id="uxr-54-H7x"/>
</constraints>
</view>
<connections>
<outlet property="cancelFiveSecondDelayButton" destination="D8O-EX-Wz2" id="jcC-ea-gnG"/>
<outlet property="fiveSecondDelayButton" destination="Jlc-qY-t9o" id="F1x-Yq-iX9"/>
<outlet property="fiveSecondDelayLabel" destination="F9h-Gs-DqK" id="Muq-hp-Q7X"/>
<outlet property="threeSecondDelayButton" destination="cSB-JX-5mZ" id="EhZ-G4-x1Z"/>
<outlet property="threeSecondDelayLabel" destination="XoN-Av-y9P" id="w8i-70-dfz"/>
<outlet property="throttledTextField" destination="JaS-iE-rER" id="6Rv-bA-10r"/>
<outlet property="throttledTextView" destination="y8E-i6-n2k" id="7cy-oK-x5f"/>
</connections>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="655"/>
<point key="canvasLocation" x="75" y="638"/>
</scene>
</scenes>
</document>
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// General delay method that uses Grand Central Dispatch to execute a
// block after a specified number of seconds has elapsed.
//
// Basic usage, execute command after N seconds:
//
// delay(N)
// {
// // do something
// }
//
// Idiom for setting up a command that runs every N seconds and resets to N
// seconds if called sooner than that is:
//
// var myCommand:CancellableDelayedCommand
// …
// myCommand = myCommand.reset() ?? delay(N)
// {
// // do something
// }
//
// Credits:
//
// Inspried by the work of Cezary Wojcik, Matt Neuburg, and Evgenii Rtishchev:
//
// * https://stackoverflow.com/a/24034838/253485
// * https://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861
// * https://github.com/katleta3000/CancelBlocks
//
// Copyright © 2015 Aral Balkan. Released with ♥ by Ind.ie under the MIT License.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
import Foundation
// MARK: Public API
func delay(delay:Double, block:dispatch_block_t) -> CancellableDelayedCommand
{
return CancellableDelayedCommand(delay: delay, block: block)
}
// MARK: - Class
class CancellableDelayedCommand
{
var originalBlock:dispatch_block_t
var delayedBlock:dispatch_block_t?
var cancelled:Bool
var executed:Bool
var delay:Double
init(delay:Double, block:dispatch_block_t)
{
self.delay = delay
self.originalBlock = block
self.executed = false
self.cancelled = false
// println("New CancellableDelayedCommand: \(self)")
if delay < 0.0
{
// Special case. If delay is negative, run the closure on the same stack frame.
// If you want to run the closure on the next stack frame, pass 0.0.
block()
self.executed = true
return
}
// Create a delayed block that checks that the command
// has not been cancelled before it calls it.
self.delayedBlock =
{
dispatch_block_t in
if !self.cancelled
{
// println("\(self): delayed block about to dispatch!")
dispatch_async(dispatch_get_main_queue(), block)
self.executed = true
}
// else
// {
// println("\(self): delayed block NOT dispatching (cancelled).")
// }
self.delayedBlock = nil
}
// Set up the delayed dispatch.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue())
{
dispatch_block_t in
if (self.delayedBlock != nil)
{
self.delayedBlock!()
}
}
}
func cancel()
{
// println("\(self): Cancelling.")
cancelled = true
}
func reset() -> CancellableDelayedCommand?
{
//
// Cancels this command and creates and returns a new one
// with the delay timer reset.
//
// println("\(self): Reset.")
cancel()
return CancellableDelayedCommand(delay: self.delay, block: self.originalBlock)
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Handle
//
// Provide a simple, human interface for handling notifications.
//
// Copyright © 2015 Aral Balkan.
// Released with ♥ by Ind.ie under the MIT License.
//
//////////////////////////////////////////////////////////////////////////////////////////
import Foundation
let 📡:NSNotificationCenter = NSNotificationCenter.defaultCenter()
public typealias NotificationBlock = (NSNotification!) -> Void
//
// MARK: - Class
//
public class NotificationHandler:NSObject
{
var handler:NotificationBlock
init(handler:NotificationBlock)
{
self.handler = handler
}
public func handlerProxy(notification:NSNotification!)
{
handler(notification)
}
public func remove()
{
📡.removeObserver(self)
}
}
////////////////////////////////////////////////////////////////////////////////
//
// MARK: - Closure-based API (preferred)
//
////////////////////////////////////////////////////////////////////////////////
//
// MARK: - Handling notifications
//
// (When you no longer need the returned notification handler, call its
// remove method. For example, you can define the notification handler
// in a view controller’s viewWillAppear() method and remove it in its
// viewWillDisappear() method.
//
public func handle(notificationName:String, with block:NotificationBlock) -> NotificationHandler
{
//
// Instead of using the block-based methods of NSNotificationCenter, create an observer
// object and return that for easy removing of the observer, etc.
//
let observer = NotificationHandler(handler: block)
📡.addObserver(observer, selector: "handlerProxy:", name: notificationName, object: nil)
return observer
}
public func handle(notificationName:String, from object:AnyObject?, with block:NotificationBlock) -> NotificationHandler
{
let observer = NotificationHandler(handler: block)
📡.addObserver(observer, selector: "handlerProxy:", name: notificationName, object: object)
return observer
}
//
// MARK: - Posting notifications
//
public func post(notificationName:String, from object:AnyObject?, with userInfo:[NSObject : AnyObject]?)
{
// println("About to post: \(notificationName) notification from \(object) with userInfo: \(userInfo)")
📡.post(notificationName, from: object, with: userInfo)
}
public func post(notificationName:String, from object:AnyObject?)
{
📡.post(notificationName, from: object, with: /* userInfo as */ nil)
}
public func post(notificationName:String)
{
📡.post(notificationName)
}
////////////////////////////////////////////////////////////////////////////////
//
// MARK: - Selector-based API
//
////////////////////////////////////////////////////////////////////////////////
//
// MARK: - Handling notifications
//
public func handle(notificationName:String, with selector:Selector, on observer:AnyObject)
{
📡.addObserver(observer, selector: selector, name: notificationName, object: nil)
}
public func handle(notificationName:String, from object:AnyObject?, with selector:Selector, on observer:AnyObject)
{
📡.addObserver(observer, selector: selector, name: notificationName, object: object)
}
//
// MARK: - Removing notification handlers
//
public func remove(#observer:AnyObject, forNotificationNamed name:String?)
{
📡.removeObserver(observer, name: name, object: nil)
}
public func remove(#observer:AnyObject, forNotificationNamed name:String?, from object:AnyObject?)
{
📡.removeObserver(observer, name: name, object: object)
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Notification Center Extensions
//
// Syntactic sugar: let’s make the addObserver and removeObserver calls literate.
//
// (Note: the global handle and post functions in Handle.swift are the preferred API
// but you can of course use the extended methods directly if you like.)
//
// Copyright © 2015 Aral Balkan.
// Released with ♥ by Ind.ie under the MIT License.
//
//////////////////////////////////////////////////////////////////////////////////////////
import Cocoa
//
// MARK: - Extension
//
extension NSNotificationCenter
{
//
// MARK: - Adding observers
//
public func handle(notificationName:String, with selector:Selector, on observer:AnyObject)
{
self.addObserver(observer, selector: selector, name: notificationName, object: nil)
}
public func handle(notificationName:String, from object:AnyObject?, with selector:Selector, on observer:AnyObject)
{
self.addObserver(observer, selector: selector, name: notificationName, object: object)
}
//
// MARK: - Removing observers
//
public func remove(#observer:AnyObject, forNotificationNamed name:String?)
{
self.removeObserver(observer, name: name, object: nil)
}
public func remove(#observer:AnyObject, forNotificationNamed name:String?, from object:AnyObject?)
{
self.removeObserver(observer, name: name, object: object)
}
//
// MARK: - Posting notifications
//
public func post(notificationName:String, from object:AnyObject?, with userInfo:[NSObject : AnyObject]?)
{
self.postNotificationName(notificationName, object: object, userInfo: userInfo)
}
public func post(notificationName:String, from object:AnyObject?)
{
self.post(notificationName, from: object, with: /* userInfo as */ nil)
}
public func post(notificationName:String)
{