KEMBAR78
Александр Зимин (Alexander Zimin) — Магия Swift | PDF
2
• Nested Types
• Generics
• Protocols
• Protocol-Oriented Programming
• Mirror Type and Reflection
3
Why Swift?
4
It’s fast 🚀 It’s powerful 💪 It’s awesome 🏆
Why Swift?
5
Colors
6
Colors
7
view.backgroundColor =
UIColor(hexString: "6094EA")
view.backgroundColor = UIColor(.strongGray)
view.backgroundColor = UIColor.strongGray
8
Expectation RealityOld
9
extension UIColor {
static var tableElementsSeparator: UIColor {
return UIColor(.strongGray)
}
static var barsSeparator: UIColor {
return UIColor(.red)
}
static var barsBackground: UIColor {
return UIColor(.gray)
}
}
Type Omission
10
extension UIColor {
static var tableElementsSeparator: UIColor {
return UIColor(.strongGray)
}
static var barsSeparator: UIColor {
return UIColor(.red)
}
static var barsBackground: UIColor {
return UIColor(.gray)
}
static var toolBox: UIColor {
return UIColor(.gray)
}
static var activeControl: UIColor {
11
extension UIColor {
static var tableElementsSeparator: UIColor {
return UIColor(.strongGray)
}s
static var barsSeparator: UIColor {
return UIColor(.red)
}s
static var barsBackground: UIColor {
return UIColor(.gray)
}s
}s
12
extension UIColor {
struct Separator {
static var tableElements: UIColor {
return UIColor(.strongGray)
}s
static var bars: UIColor {
return UIColor(.red)
}s
}
}s
Struct Enum
13
extension UIColor {
enum Separator {
static var tableElements: UIColor {
return UIColor(.strongGray)
}s
static var bars: UIColor {
return UIColor(.red)
}s
}
}s
14
let activeStateColor =
UIColor.Control.Button.activeStateTitle
button.setTitleColor(activeStateColor, for: .normal)
15
Generics
16
Generics<T>
17
18
struct StoriesDisplayCollection {
var stories: Results<StoryEntity>
var count: Int {
return stories.count
}
func nameAtIndex(index: Int) -> String {
return stories[index].name
}
}
19
struct StoriesDisplayCollection {
var stories: Results<StoryEntity>
var count: Int {
return stories.count
}
func nameAtIndex(index: Int) -> String {
return stories[index].name
}
}
Stories
20
struct StoriesDisplayCollection {
var stories: Results<StoryEntity>
var count: Int {
return stories.count
}
func nameAtIndex(index: Int) -> String {
return stories[index].name
}
}
21
struct StoriesDisplayCollection {
var stories: Results/List<StoryEntity>
}
struct StoriesDisplayCollection {
var stories: TemplateModelsCollection<StoryEntity>
}
22
struct TemplateModelsCollection<T: TemplateEntity>
where T: Object {
}
23
enum Content {
case result(Results<T>)
case list(List<T>)
case empty
subscript(index: Int) -> T {
switch self {
case let .result(model):
return model[index]
case let .list(list):
return list[index]
case .empty:
return T.templateEntity
}
}
}
Nested
Same T, Swift 3.1+
24
struct TemplateModelsCollection<T: TemplateEntity>
where T: Object {
init(dataCollection: Results<T>, templatesCount: Int = 5) {
content = Content.result(dataCollection)
values = List<T>()
generateFakeData(templatesCount: templatesCount)
}
}
Template One
25
struct TemplateModelsCollection<T: TemplateEntity>
where T: Object {
var count: Int {
if isLoading && content.count == 0 {
return values.count
} else {
return content.count
}
}
}
Template One
26
27
Protocols
28
protocol Summable {
static func +(lhs: Self, rhs: Self) -> Self
}
extension Int: Summable { }
extension String: Summable { }
public func +(lhs: Int, rhs: Int) -> Int
public func +(lhs: String, rhs: String) -> String
29
protocol Summator {
associatedtype Value
func sum(a: Value, b: Value) -> Value
}
30
protocol Summator {
associatedtype Value
func sum(a: Value, b: Value) -> Value
}
extension Summator where Value: Summable {
func sum(a: Value, b: Value) -> Value {
return a + b
}
}
31
struct IntSummator: Summator {
typealias Value = Int
}
let summator = IntSummator()
print(summator.sum(a: 5, b: 10)) // 15
32
• We have Self/associatedtype for future type
implementation
• We can specify rules for associatedtype
• We can extend protocols with logic
• We can specify constraints for protocol extensions
33
Protocol-Oriented
Programming
34
youtube.com/watch?v=71AS4rMrAVk
35
• Value Type over Reference Type
• No inheritance
• No mutability
• Advanced usage of protocols and its extensions
36Array
RandomAccessCollection MutableCollection
BidirectionalCollection
Sequence
Collection
37
Array
RandomAccessCollection
MutableCollection
BidirectionalCollection
Sequence
Collection
ExpressibleByArrayLiteral
CustomReflectable
RangeReplaceableCollection
CustomStringConvertible
CustomDebugStringConvertible
38
Array
RandomAccessCollection
MutableCollection
BidirectionalCollection
Sequence
Collection
ExpressibleByArrayLiteral
CustomReflectable
RangeReplaceableCollection
CustomStringConvertible
CustomDebugStringConvertible
_ArrayProtocol
_ObjectiveCBridgeable
Encodable
Decodable
MyArrayBufferProtocol
MyPrintable
P5
SplittableCollection
BuildableCollectionProtocol
MutableCollectionAlgorithms
39
Array
RandomAccessCollection
MutableCollection
BidirectionalCollection
Sequence
Collection
ExpressibleByArrayLiteral
CustomReflectable
RangeReplaceableCollection
CustomStringConvertible
CustomDebugStringConvertible
Dictionary
Collection
CustomStringConvertible
CustomDebugStringConvertible
CustomReflectable
Sequence
-
-
ExpressibleByDictionaryLiteral
-
-
40
Array
RandomAccessCollection
MutableCollection
BidirectionalCollection
Sequence
Collection
ExpressibleByArrayLiteral
CustomReflectable
RangeReplaceableCollection
CustomStringConvertible
CustomDebugStringConvertible
List
Realm One
RandomAccessCollection
LazyCollectionProtocol
BidirectionalCollection
Sequence
Collection
ExpressibleByArrayLiteral
RealmCollection
RangeReplaceableCollection
CustomStringConvertible
ThreadConfined
41
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
42
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
Protocol
43
Swift 3.1+
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
44
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
Generic Element
45
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
Index == Int
subscript(position: Self.Index)
-> Self.Iterator.Element { get }
46
extension Collection where Index == Int {
var second: Iterator.Element? {
guard self.count > 1 else { return nil }
return self[1]
}
}
var array = ["A", "B", "C"]
print(array.second) // Optional("B")
47
• Follow I from SOLID
• Implement default behaviour in protocol extensions
• Implement generic based behaviour
• Combine multiply protocols or “inherit” them
The interface-segregation principle (ISP) states that no client
should be forced to depend on methods it does not use.
48
49
protocol CellViewModel {
associatedtype CellType: UIView
func setup(cell: CellType)
}
Generic
Generic
50
protocol CellViewModel: CellViewAnyModel {
associatedtype CellType: UIView
func setup(cell: CellType)
}
Non generic
51
protocol CellViewAnyModel {
static var cellAnyType: UIView.Type { get }
func setupAny(cell: UIView)
}
associatedtype CellType: UIView
func setup(cell: CellType)
52
extension CellViewModel {
static var cellAnyType: UIView.Type {
return CellType.self
}
func setupAny(cell: UIView) {
setup(cell: cell as! CellType)
}
}
!!!
53
• https://github.com/JohnSundell/SwiftTips
• https://developer.apple.com/swift/blog/
• https://swift.org/blog/
• https://swiftnews.curated.co
• https://www.raizlabs.com/dev/2016/12/swift-method-
dispatch/
• https://github.com/ole/whats-new-in-swift-4
54
• https://github.com/JohnSundell/SwiftTips
• https://developer.apple.com/swift/blog/
• https://swift.org/blog/
• https://swiftnews.curated.co
• https://www.raizlabs.com/dev/2016/12/swift-method-
dispatch/
• https://github.com/ole/whats-new-in-swift-4
55
@ZiminAlex

Александр Зимин (Alexander Zimin) — Магия Swift