Мыслетопливо
Конечно, нередко нам кажется, что заканчивается именно время, но на поверку это оказывается следствием опустошения бачка с мыслетопливом: сначала иссякает оно, потом врубается медленное мышление, как результат мы начинаем «тупить» и испытывать затруднения даже с элементарными вещами, делая их во много раз дольше обычного.
...
UML: Связи между сущностями (объектами)
Основные связи при проектировании Архитектуры
Реализация протокола/интерфейса или Имплементация. | |
Явная связь | |
Композиция — внутренняя зависимость | |
Агрегация (инъекция зависимости) внешняя зависимость |
Понизить связанность кода путём скрытия конкретной реализции за протоколами и для этого в UML диаграмме нам подходит такая связь ...
Например: у нас есть протокол и объекты которые на него подписаны (реализующие этот протокол).
protocol Configurable { func configure(with model: Model) }
Driver
Дравйвер
классная вещь в RxSwift, позволяет:
- Восстанавливаться от ошибок.
- Является Observable
- Автоматически переводит подписку drive в Main thread, что делает его идеальным для UI
- Описывать обработку ошибок внутри, не передавая ошибку по цепочке.
... asDriver() .drive({ value in }) ...
Итерация по enum
enum State { case none case one case two }
Конформим State под протокол CaseIterable
extension State: CaseIterable {}
После этого мы можем итерироваться
State.allCases.forEach { print($0) }
Интересные Callback'и
Объявляем тип для callback замыкания
typealias RegStateCallbackType = @convention(c) (_ accountId: pjsua_acc_id) -> Void
var onRegStateCallback: RegStateCallbackType?
И можно тогда заюзать следующим образом
endpointCfg.cb.on_reg_state = onRegStateCallback
Swift String to C char *
void mi_connect_device(char *device_name);
func connect(to device: String) { device.withCString { let int8Pointer = UnsafeMutablePointer<Int8>(mutating: $0) mi_connect_device(int8Pointer) } }
Время сборки в Xcode
Хочу видеть время сборки проекта
Вариант 1:
defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES
Вариант 2:
в папке с проектом выполнить в консоле комманду
time xcodebuild
Запуск из консоли
xcodebuild -workspace CallKitExample.xcworkspace -scheme CallKitExample -showBuildTimingSummary
RxSwift кастомная View'ха
Пишем своё расширение кастомной вьюхи.
import UIKit import RxSwift import RxCocoa class CustomControl: UIControl { var value: Int = 0 { didSet { sendActions(for: .valueChanged)} } override init(frame: CGRect) { super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func toggle() { if value == 0 { backgroundColor = .green value = 1 } else { backgroundColor = .red value = 0 } } } extension Reactive where Base: CustomControl { var value: ControlProperty<Int> { return base.rx.controlProperty(editingEvents: UIControlEvents.valueChanged, getter: { customView in return customView.value }, setter: { customView, newValue in customView.value = newValue }) } }
И теперь использовать можно так
customView.rx.value .subscribe(onNext: { value in print("changed my value -> \(value)") }) .disposed(by: bag)
Login screen
Реализовал Login screen на VIPER, хотя в несколько облегчённом варианте, скорее всего ещё допилю взаимодействие между модулями. Router — > Router + Presenter
VIPER
V — View (Views + ViewControllers)
I — Interactor — бизнес логика модуля
P — Presentor (ViewModels and prepare)
E — Entities — (Models)
R — Router
Следующие слова из статьи с New York Times
Слова:
- along — вместе
- being — являющийся
- accused — обвиняемый
- whistling — свистящий
- kindle — зажигать
- crumbling — рушиться
- wither — увядать
- apart — кроме
- neglected — пренебрегли
- slaughter — забой скота
Мои попытки учить английский самостоятельно.
Переодически говорю себе, что мне нужен английский. хотя кроме потребности иногда что-то прочитать профессионального по работе, казалось бы жесткой необходимости знать английский и нет.
Хотелось бы проходить собеседование на английском, говорить в кафе как нейтив.
Попробую каждый день читать быстро 5-10 минут по статье из New York Times или The Times
Взял статью.
Решил выписывать неизвестные обороты из неё.
They drew blood from him
Они вытянули кровь из него
caught up in a vast Chinese campaign of surveillance and oppression.
втянутый в обширную китайскую кампанию слежки и угнетения.
Посмотрим смогу ли я продержаться хотя бы неделю.
Оказалось что статья это много для 5 минут, учитывая что и сюда надо оформить пару строк, думаю стоит тогда брать пару абзацев. Возможно дойду до того что буду выписывать основные мысли статей.
Список слов:
Dreamy day — мечтательные дни
Swift KVO
Модель
import Foundation @objc class Card: NSObject { @objc dynamic var life: Int = 0 @objc dynamic var atack: Int = 0 @objc dynamic var defense: Int = 0 }
Задаём переменную для invalidate()
var cardObserver: NSKeyValueObservation?
Подписываемся на изменения и вешаем обработчик
let card = Card() cardObserver = card.observe(\Card.life, options: .old, changeHandler: { card, change in print("Changed life value \(card.life) -> ", change.oldValue ?? -1) })
Соответсвенно когда мы меняем значение переменной `life` то вызывается наш обработчик
card.life = 12 card.life = 1 card.life = 34
Swift: setTimeOut
DispatchQueue.main.asyncAfter(deadline: .now() + 0.600) { // some code }
RxSwift: создаём реактивное расширение
Расширение
extension Reactive where Base: NSView { public var alphaValue: ControlProperty<CGFloat> { let source = self.observeWeakly(CGFloat.self, "alphaValue", options: [.initial, .new]) .filter { $0 != nil }.map { $0! } .takeUntil(deallocated) let observer = Binder<CGFloat>(base) { control, value in control.alphaValue = value } return ControlProperty(values: source, valueSink: observer) } }
Применение
подписываемся на изменения переменной
view.rx.alphaValue.subscribe(onNext: { value in print("val->", value) }) .disposed(by: disposeBag)
меняем значение по слайдеру
slider.rx.value.subscribe({ [weak self] item in let newValue = Int( item.element ?? 0 ) self?.view.alphaValue = newValue }) .disposed(by: disposeBag)
RxSwift: Создание реактивной переменной
Код должен быть прозрачным
import RxSwift
Способ 1
Создаём переменную
var hitPoints = Variable<Int>(10)
Изменение значение переменной
card.hitPoints.value = hp
Подписка на изменение
card.hitPoints.asObservable().subscribe(onNext: { [weak self] value in print("Your hit points ->", value) self?.labelHitPoints.stringValue = "\(value)" }) .disposed(by: bag)
Способ 2
Создаём переменную
var rxMana = BehaviorRelay<Int>(value: 0)
Вешаем обработчик на реактивную переменную
self.rxMana.subscribe(onNext: { value in print("Your level mana ->", value) }) .disposed(by: disposeBag)
Ну и где-нить меняем значение переменной
rxMana.accept(newValue)
Как передать в vue filter контекст компоненты
Задача
Во vue фильтры являются чистыми функциями и они ничего не знают об окружении из которого вызываются, а обратиться к данным компоненты из них бывает очень полезно, а иногда просто жизненно необходимо.
Решение
в шаблоне компоненты
:value="value | filterNumber(this)"
в компоненте
... filters: { filterNumber: function(value, self) { console.log("this->", self.propName) return value; } }, ...
UX design
Один из основных навыков UX-дизайнера — это умение рассказывать о сложных вещах простыми словами.
Делая UX простым, вы сможете влиять на окружающих.
IoT Asset Tracker
IoT Asset Tracker
Отслеживание состояния партии готовой продукции от места производства до конечного заказчика
Стек:
- MapKit,
- Swift,
- MVVM,
- Realm,
- Moya.