Many of the codes are copied from PSPDFKit's articles about writing Swiftier Objective-C.
import Swiftier;
to use the following.
You may now use let and var to declare the type of a variable, when the type can be inffered by compiler.
They are equivalent to __auto_type const
and __auto_type
. If ObjC++ is used, they are equivalent to auto const
and auto
.
Usage:
let array = @[@1,@2,@3];
var number = 1;
You may use guard
to guard a specific condition now. guard (condition)
is equivalent to if(condition){}
, a more expressive way to do something when a condition is not met, if you call guard (condition)
alone, it will do nothing, you should use the "swift way" to guard things out.
guard (condition) else { /* do something else */ }
Which is equivalent to swift's
guard condition else { /* do something else */ }
Which is good for the cases when you need to return nil when some conditions are not met.
let a = somethingElse;
guard (a != nil) else { return nil; }
[a continueToSomeOtherThings];
Run a nullable block without null checking.
safeBlock(block, arguments);
// is equivalent to
if (block) block(arguments);
And safely run block on a specific thread is also possible with
asyncQueueBlock(queue, block, ...);
mainQueueBlock(block, ...);
Checks a potential nill/null object, returns the computed value or, if the object is nill, returns the default value. Good when the object is extremely long to express (often happens in objc) that you don't have to type things twice.
- (void)updateTextToMatchAButton {
self.label.title = safelyUnwrap(self.someView.button.title, defaultTitle);
// instead of
self.label.title = self.someView.button.title ? self.someView.button.title : defaultTitle;
}
When collection has type information, we may use
foreach(element, collection) { ... }
This four methods are available for NSArray
and NSMutableArray
. They each takes in a block, and runs the block to each element inside.
Usage:
let array = @[@1, @2, @3];
let mappedArray = [array swt_map:^AnotherType(NSNumber *number) {
return [AnotherType initWith:number];
}];
// result -> @[AnotherType(@1), AnotherType(@2), AnotherType(@3)];
let filteredArray = [array swt_filter:^BOOL(NSNumber *number) {
return number.intValue > 2;
}];
// result -> @[@3];
[array swt_forEach:^BOOL(NSNumber *number) {
NSLog(number);
}];
// prints: 1 2 3
let array = @[@1, null, @3];
let mappedArray = [array swt_compactMap:^AnotherType(NSNumber *number) {
return [AnotherType initWith:number];
}];
// result -> @[AnotherType(@1), AnotherType(@3)];
- (void)foo {
swt_defer { NSLog(@"2") };
NSLog(@"1");
}
// prints ->
// 1
// 2
keyPath(object, path)
to get compiler checked key path instead of stringly typed one.
Some collection types now have type information in copy
or mutableCopy
.
Some struct types like CGRect
, CGPoint
... can be boxed into NSValue
with
let rect = CGRectMake(1,2,3,4);
let value = @(rect);