The translation was prepared as part of the set for the course "iOS Developer. Professional" .
We invite everyone to an open demo lesson “Machine Learning in iOS using CoreML and CreateML: images, text, sound” . In the lesson we will discuss:
1. The main architectures of neural networks and their optimized versions for mobile devices;
2. Possibilities of CoreML 3 and 4, training on an iOS device;
3. Self-training of the image classifier using CreateML and using it with Vision;
4. Using trained models to work with text and sound in iOS.
(result builders) Swift — « ». Swift 5.4 Xcode 12.5 . function builders (« »). , , SwiftUI.
: , Swift, . UIKit, , .
?
- (DSL), . SwiftUI @ViewBuilder
, :
struct ContentView: View {
var body: some View {
// This is inside a result builder
VStack {
Text("Hello World!") // VStack and Text are 'build blocks'
}
}
}
( VStack, Text
) View
. , « » View
«» View
. , .
View
SwiftUI, , body
@ViewBuilder
:
@ViewBuilder var body: Self.Body { get }
, .
var constraints: [NSLayoutConstraint] = [
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
]
// Boolean check
if alignLogoTop {
constraints.append(swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor))
} else {
constraints.append(swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor))
}
// Unwrap an optional
if let fixedLogoSize = fixedLogoSize {
constraints.append(contentsOf: [
swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width),
swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
])
}
// Add a collection of constraints
constraints.append(contentsOf: label.constraintsForAnchoringTo(boundsOf: view)) // Returns an array
// Activate
NSLayoutConstraint.activate(constraints)
, . .
— . :
@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor) // Single constraint
if alignLogoTop {
swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
} else {
swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor) // Single constraint
}
if let fixedLogoSize = fixedLogoSize {
swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
}
label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
}
, ?
, .
AutolayoutBuilder
@resultBuilder
, :
@resultBuilder
struct AutolayoutBuilder {
// .. Handle different cases, like unwrapping and collections
}
« » , , . .
:
@resultBuilder
struct AutolayoutBuilder {
static func buildBlock(_ components: NSLayoutConstraint...) -> [NSLayoutConstraint] {
return components
}
}
components ( ). , . , .
:
@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
}
« »
. constraintsForAnchoringTo(boundsOf:)
, . , :
:
Cannot pass array of type ‘[NSLayoutConstraint]’ as variadic arguments of type ‘NSLayoutConstraint’ — «[NSLayoutConstraint]» «NSLayoutConstraint»
, Swift . . , :
, , , . , , .
, , NSLayoutConstraint
, :
protocol LayoutGroup {
var constraints: [NSLayoutConstraint] { get }
}
extension NSLayoutConstraint: LayoutGroup {
var constraints: [NSLayoutConstraint] { [self] }
}
extension Array: LayoutGroup where Element == NSLayoutConstraint {
var constraints: [NSLayoutConstraint] { self }
}
, . , — [NSLayoutConstraint
].
, LayoutGroup
:
@resultBuilder
struct AutolayoutBuilder {
static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
return components.flatMap { $0.constraints }
}
}
flatMap
. , flatMap
compactMap
, compactMap flatMap: ?
, , « »:
@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
}
, , — . , .
buildOptional(..)
:
@resultBuilder
struct AutolayoutBuilder {
static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
return components.flatMap { $0.constraints }
}
static func buildOptional(_ component: [LayoutGroup]?) -> [NSLayoutConstraint] {
return component?.flatMap { $0.constraints } ?? []
}
}
, .
« »:
@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
// Unwrapping an optional
if let fixedLogoSize = fixedLogoSize {
swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
}
}
— . . :
@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
// Unwrapping an optional
if let fixedLogoSize = fixedLogoSize {
swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
}
// Conditional check
if alignLogoTop {
// Handle either the first component:
swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
} else {
// Or the second component:
swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor)
}
}
« »:
@resultBuilder
struct AutolayoutBuilder {
static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
return components.flatMap { $0.constraints }
}
static func buildOptional(_ component: [LayoutGroup]?) -> [NSLayoutConstraint] {
return component?.flatMap { $0.constraints } ?? []
}
static func buildEither(first component: [LayoutGroup]) -> [NSLayoutConstraint] {
return component.flatMap { $0.constraints }
}
static func buildEither(second component: [LayoutGroup]) -> [NSLayoutConstraint] {
return component.flatMap { $0.constraints }
}
}
buildEither
LayoutGroup
.
, . !
. , .
— . AutolayoutBuilder
.
, NSLayoutConstraint
, :
extension NSLayoutConstraint {
/// Activate the layouts defined in the result builder parameter `constraints`.
static func activate(@AutolayoutBuilder constraints: () -> [NSLayoutConstraint]) {
activate(constraints())
}
:
NSLayoutConstraint.activate {
// Single constraint
swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
// Unwrapping an optional
if let fixedLogoSize = fixedLogoSize {
swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
}
// Conditional check
if alignLogoTop {
// Handle either the first component:
swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
} else {
// Or the second component:
swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor)
}
}
, , UIView
:
protocol SubviewContaining { }
extension UIView: SubviewContaining { }
extension SubviewContaining where Self == UIView {
/// Add a child subview and directly activate the given constraints.
func addSubview<View: UIView>(_ view: View, @AutolayoutBuilder constraints: (Self, View) -> [NSLayoutConstraint]) {
addSubview(view)
NSLayoutConstraint.activate(constraints(self, view))
}
}
:
let containerView = UIView()
containerView.addSubview(label) { containerView, label in
if label.numberOfLines == 1 {
// Conditional constraints
}
// Or just use an array:
label.constraintsForAnchoringTo(boundsOf: containerView)
}
, UIView
. , label
.
?
, , : , ?
, , , . , , .
, , . « », ( ) .
— Swift 5.4. - , . , , .
«Machine Learning iOS CoreML CreateML: , , »