Nest is a library which makes Foundation and Swift works more seamlessly and offers some great missing helpers, utilities in Foundation.
pod "Nest.swift"
import Nest
to your Swift source fileEmebed Binaries
field in your target’s general page if you are building an app. Or add Nest to your Linked Frameworks and Libraries
field in your target’s general page if you are building a framework.import Nest
to your Swift source fileNest
This class comes out of an answer I wrote on Stack Overflow: Intercept Objective-C delegate messages within a subclass. But as the original code was written in Objective-C and Swift's code-level-safety makes it become impossible that assign an object of any type to a pointer, I rewrote it in Swift and added some additional code to make it work in Swift now.
NSProtocolInterceptor
is an object which masquerade itself as the protocol type(s) which you assigned at the initialization time, and intercepts message to the middle man if it could respond which originally intended to send to the receiver.
NSProtocolInterceptor(aProtocol: Protocol
)
NSProtocolInterceptor(protocols: [Protocol]
)
NSProtocolInterceptor(protocols: Protocol ...
)
class MyScrollView: UIScrollView, UIScrollViewDelegate {
let delegateInterceptor: NSProtocolInterceptor
func scrollViewDidScroll(scrollView: UIScrollView) {
if self.delegate?.respondsToSelector("scrollViewDidScroll:") == true {
self.delegate?.scrollViewDidScroll?(scrollView)
}
}
required init(coder aDecoder: NSCoder) {
delegateInterceptor = NSProtocolInterceptor(aProtocol: UIScrollViewDelegate.self)
super.init(coder: aDecoder)
delegateInterceptor.middleMan = self
super.delegate = delegateInterceptor as? UIScrollViewDelegate
}
override init(frame: CGRect) {
delegateInterceptor = NSProtocolInterceptor(aProtocol: UIScrollViewDelegate.self)
super.init(frame: frame)
delegateInterceptor.middleMan = self
super.delegate = delegateInterceptor as? UIScrollViewDelegate
}
}
For UIKit bridging header claims UIScrollView
's delegate
property as unowned(unsafe)
and doesn't mark UIScrollViewDelegate
up as a class only protocol, we cannot override the delegate
property in Swift for now. So let's override it in Objective-C.
@import UIKit;
#import "ProductModuleName-Swift.h"
@interface MyScrollView (OverrideDelegate)
@end
@import Nest;
#import "MyScrollView+OverrideDelegate.h"
@implementation MyScrollView (OverrideDelegate)
- (id <UIScrollViewDelegate>)delegate {
return (id <UIScrollViewDelegate>)self.delegateInterceptor.receiver;
}
- (void)setDelegate:(id <UIScrollViewDelegate>)delegate {
super.delegate = nil;
self.delegateInterceptor.receiver = delegate;
super.delegate = (id <UIScrollViewDelegate>)self.delegateInterceptor;
}
@end
Reusing is an usual way to optimize a program's performance. This class it designed for making reusing simpler.
NSReuseCenter
offers an enqueue and dequeue mechanism for objects conform to the NSReusable
protocol.
let theReuseCenter = NSReuseCenter<AParticularReusable>()
theReuseCenter.enqueueUnused(anUnusedObject)
theReuseCenter.dequeueReusableWithReuseIdentifier(aReuseIdentifier)
theReuseCenter.reusableForReuseIdentifier(aReuseIdentifier)
There might be a situation you had encountered before where you wanted to find an NSObjectProtocol
conformed object in a protocol-constrained collection and Swift didn't suppose your NSObjectProtocol
conformed object implements the Equatable
protocol which made you unable to use the find
function in Swift standard library. These collection of functions assume that any NSObjectProtocol
conformed object has a clear understand on isEqual:
function and use that function to evaluate equality between objects.
Check an NSObjectProtocol
conformed object is contained in a collection of NSObjectProtocol
conformed objects.
NSContains<C
where C
: CollectionType
, C.Generator.Element
: NSObjectProtocol
>(domain: C
, element: C.Generator.Element
) -> Bool
Find the index of an NSObjectProtocol
conformed object in a collection of NSObjectProtocol
conformed objects.
NSFind<C
: CollectionType
where C.Generator.Element
: NSObjectProtocol
>(domain: C
, value: C.Generator.Element
) -> C.Index?
Calculate intersected objects in two collections of NSObjectProtocol
conformed objects.
NSIntersected<C
: ExtensibleCollectionType
where C.Generator.Element
: NSObjectProtocol
>(collectionA: C
, collectionB: C
) -> C
Evaluate differences between two collections of NSObjectProtocol
conformed objects.
NSDiff<Seq
: SequenceType
where Seq.Generator.Element
: NSObjectProtocol
>(from fromSequence: Seq?
, to toSequence: Seq?
, differences: SequenceDifference
, unchangedComparator: ((Seq.Generator.Element, Seq.Generator.Element)->Bool)
= default, usingClosure changesHandler: (change: SequenceDifference, fromElement: (index: Int, element: Seq.Generator.Element)?, toElement: (index: Int, element: Seq.Generator.Element)?) -> Void
)
Remove an NSObjectProtocol
conformed object in a collection of NSObjectProtocol
conformed objects.
NSRemove<C
: RangeReplaceableCollectionType
where C.Generator.Element
: NSObjectProtocol
, C.Index
: protocol<Comparable, BidirectionalIndexType>
> (inout collection: C
, elements: C
) -> C
Check if selector belongs to a protocol.
sel_belongsToProtocol(aSelector: Selector
, aProtocol: Protocol
) -> Bool
Swizzle a selector with an implementation on a class. The original implementation would be connected with a selector which consists of the given prefix and its original selector.
class_swizzleClass(aClass: AnyClass
, selector: Selector
, withImplementation: IMP
, selectorPrefix: String
) -> Bool
Comparable
I made NSDate conforms to Comparable
to get avoid of comparing two NSDate
objects by using its compare:
function.
let now = NSDate()
let tenSecondsBefore = now.dateByAddingTimeInterval(-10)
if now > tenSecondsBefore {
println("Now is later than ten seconds before")
}
Search all occurrence for given string in an NSString
without using regular expression.
let aString = "This is a string"
let aStringInNSString = aString as NSString
let occurrences = aStringInNSString.rangesOfString("s", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil)
let anNSRange = NSRangeMake(location: 0, length: 10)
let anError = NSError(error: anError, anotherError: anOtherError)
let anError = NSError(errorPointer:anErrorPointer, secondError: secondError)
let anError = NSError(errors: errors)