Git Hub
коротко
Ctrl + ↑ Позднее

MPM

11 сентября 2018, 14:35

Real-time Production Management

Это приложение предназначенное для решения задач

  1. Мониторинг текущего производственного процесса,
  2. Планирования изменений и связанных с этим затрат,
  3. Анализа и оптимизации процесса выпуска продукции.

Стек:

  • Swift,
  • MVVM,
  • Realm,
  • Moya,
  • RxSwift,
  • GCD.

Посмотреть все сим-линки в системе

28 августа 2018, 11:27
find / -type l -ls

Посмотреть все изменёёные файлы за последние N минут

find . -type f -mmin -30

Swift

16 июня 2018, 18:29

Разница между датами

func calcDiff(between start: String, and end: String ) -> String {
        if
            let endTime = Date.from(end),
            let startTime = Date.from(start)
        {
            return Calendar.current.date(from: Calendar.current
                .dateComponents([.hour, .minute], from: startTime, to: endTime))?
                .formatted("HH:mm") ?? "--:--"
        }
        
        printError("Can't convert time ")
        return  "--:--"
    }

Collection with safe index

15 июня 2018, 23:41
extension Collection where Indices.Iterator.Element == Index {
    subscript(safe index: Index) -> Iterator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

Очередь

14 июня 2018, 19:06

Алгоритмы с структуры данных

protocol QueueProtocol {
    associatedtype Element
    mutating func append(element: Element)
    mutating func next() -> Element?
}

Реализация очереди:

struct Queue<E>: QueueProtocol {
    
    typealias Element = E
    
    var elements: [E] = []
    
    mutating func append(element: E) {
        elements.append(element)
    }
    
    mutating func next() -> E? {
        if elements.first == nil {
            return nil
        }
        
        return elements.removeFirst()
    }
    
}

Пример применения очереди:

var queue = Queue<Int>()

queue.append(element: 1)
queue.append(element: 2)
queue.append(element: 3)
queue.append(element: 4)


while let e = queue.next() {
    print("E -> \(e)")
}

git: сохранение в stash по имени

17 апреля 2018, 19:47

сохранение в stash с названим/комментарием

git stash save "some message "

Dependency Injection

9 марта 2018, 10:21

Dependency Injection или DI.

Описание протокола и вариантов зависимости

protocol DependencyProtocol {
    func makeMoney() -> Float
}

class Alfa: DependencyProtocol {
     func makeMoney() -> Float {
         return 100;
     }
}

class Betta: DependencyProtocol {
     func makeMoney() -> Float {
         return 9000;
     }
}
class Wallet {
   var sourceMoney: DependencyProtocol
   
   init(source: DependencyProtocol) {
   sourceMoney = source
    }

    getMoney() -> Float {
     return sourceMoney.makeMoney()
    }
}

Использование

let myWallet = Wallet(source: Betta())
var myMoney = myWallet.getMoney()

Weak против Unowned

8 марта 2018, 21:27

В Swift эти модификаторы ссылок схожи, но не одинаковы

Weak Unowned
Слабая ссылка Да Да
Увеличивает счётчик ссылок для ARC Да Нет

Пример использования weak


Нельзя помечать weak протоколы не относящиеся к ссылочному типу

Пример использования unowned

class BaseService {
    unowned let provider: ServiceProviderProtocol
    
    init(provider: ServiceProviderProtocol) {
        self.provider = provider
    }
}

Желаю всем более обдуманного выбора при использовании weak и unowned.

Использование реактивщины в iOS приложениях на Xamarin

20 декабря 2017, 17:14
  1. Через NuGet подключаем в проект пакет ReactiveUI
  2. Прописываем там где нам надо
using ReactiveUI;
  1. Подписываемся на события
inputText.EditingChanged += (object sender, EventArgs e) => {
                Console.WriteLine("Editing value changed");
            };
C#   FRP   Xamarin

Вибрация в приложении

24 ноября 2017, 13:34

Самый быстрый способ добавить вибрацию в приложение

import AudioToolbox
... 
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate)) // vibration
...

Задчака на понимание

19 ноября 2017, 11:36

Что будет напечатано после выполнения кода ?

var foo: Bool {
	print("Вы нам")
	return false
}

var bar: Bool {
	print("не")
	return true
}

if foo && bar {
	print("нравитесь")
} else {
	print("подходите")
}

Паттерны GRASP

17 ноября 2017, 14:58

Паттерны «общей ответственности»

  • Information Expert
  • Creator
  • Controller
  • Low Coupling
  • High Cohesion
  • Polymorphism
  • Pure Fabrication
  • Indirection
  • Protected Variations

Zinc Scanner

10 ноября 2017, 10:09

Сканер штрих кодов партий готовой продукции

Стек: Swift, MVVM, AVFoundation, RxRealm, Moya(REST), GCD

Описание формата SMILES

27 октября 2017, 17:52

Описание формата SMILES

SMILES — Simply Molecule in Line-entering Structure

Условные обозначения

символ описание
= двойная связь
# тройная связь
$ четыри связи
\ хиральная связь
: — aromatic bond symbol
/ — ???

Запахи кода

24 октября 2017, 18:55

Раздувальщики

  • Длинный метод
  • Большой класс
  • Одержимость элементарными типами
  • Длинный список параметров/аргументов
  • Группы данных

Утяжелители изменений

  • Расходящиеся модификации
  • Стрельба дробью
  • Параллельные иерархии классов

Замусориватели

  • Комментарии
  • Дублирование кода
  • Ленивый класс
  • Класс данных
  • Мёртвый код
  • Теоретическая общность

Опутыватели связями

  • Завистливые функции
  • Неуместная близость
  • Цепочка вызовов
  • Посредник

Методы рефакторинга

24 октября 2017, 13:45

Временные абстрации
Временную переменную заменяем на вызов метода (выделение метода)

Предпосылки к рефакторингу

23 октября 2017, 2:16

Код повторяется
Метод слишком велик
Цикл слишком велик или слишком глубоко вложен в другие циклы
Класс имеет плохую связность
Интерфейс класса не формирует согласованную абстракцию
Метод принимает слишком много параметров
Отдельные части класса изменяются независимо от других частей
При изменении программы требуется параллельно изменять несколько классов
Вам приходится параллельно изменять несколько иерархий наследования
Вам приходится параллельно изменять несколько блоков case
Родственные элементы данных, используемые вместе, не организованы в классы
Метод использует больше элементов другого класса, чем своего собственного
Элементарный тип данных перегружен
Класс имеет слишком ограниченную функциональность
По цепи методов передаются бродячие данные
Объект посредник ничего не делает
Один класс слишком много знает о другом классе
Метод имеет неудачное имя
Данные члены сделаны открытыми
Подкласс использует только малую долю методов своих предков
Сложный код объясняется при помощи комментариев
Код содержит глобальные переменные
Перед вызовом метода выполняется подготовительный код (после вызова метода выполняется код «уборки»)
Программа содержит код, который может когда нибудь понадобиться

О Haskell по-человечески

22 октября 2017, 12:33

«Функциональное программирование — своеобразное гетто посреди мегаполиса нашей индустрии. Доля функциональных языков пока ещё очень мала, и многие разработчики побаиваются знакомства с этими языками, и с Haskell в особенности.

Вероятно, вы слышали, что Haskell — это что-то архисложное, сугубо научное и непригодное для реальной жизни? Читайте дальше, и вскоре вы убедитесь в обратном.»

( https://www.ohaskell.guide/ )

Маленькая памятка по созданию реактивной переменной

29 сентября 2017, 12:06

Подключаем реактивный свифт

import RxSwift

Создаём «сумку» для мусора, при  деините объекта все ссылки из этой сумки будут корректно зачищены

let bag = DisposeBag()

Инитим переменную и её наблюдатель

var reactiveVariable = Variable<Int>(1)
    var nabludatel = PublishSubject<Int>()

...

reactiveVariable.asObservable()
            .bind(to: nabludatel)
            .disposed(by: bag)
        
        
        nabludatel.asObservable()
            .bind  {
                print("called when changed var  -> \($0)")
            }
            .disposed(by: bag)

Применяем

reactiveVariable.value = 31337

Vuex

28 сентября 2017, 12:41

Vuex — это паттерн управления состоянием и библиотека для приложений на Vue.js. Он служит центральным хранилищем данных для всех компонентов приложения и обеспечивает предсказуемость изменения данных при помощи определённых правил.

Gett­ers

Функции возвращающие значения из store. Используйте их, когда над значениями в store надо произвести какие то действия прежде чем передать их вызвавшему. (Вы так же можете считывать напрямую.)

Muta­tions

Функции которые коммитят изменения в store. Могут быть использованы для пред-обработки значений перед сохранением. Вы так же можете изменять state напрямую

Acti­ons

Функции похожие на мутации. исключая коммиты данных во время асинхронных таксов. Они не являются обязательными, но вы должны привыкнуть использовать их всякий раз, когда присутствуют мутации.

Жизненный цикл Vuex (Life Cycle)

пример использования Getters

<template>
     <div>
        <div>Value = {{ getMyProperty }}</div>
        <div>Value = {{ getStoredProp }}</div>
    </div>
</template>

<script>
    import { mapGetters } from 'vuex';
    export default {
        computed: {
            ...mapGetters([
                'getMyProperty'
            ]),
            // or, without helper...
            getStoredProp: () => {
                  return this.$store.getters.getMyProperty;
            }
        }
    }
</script>

пример использования Mutations

<template>
    <div>
        <button @click="setMyProperty(22)">Set to 22</button>
        <button @click="setThatProp(0)">Reset to 0</button>
    </div>
</template>

<script>
    import { mapMutations } from 'vuex';
    export default {
        methods: {
            ...mapMutations([
                'setMyProperty'
            ]),
            // Or without helper...
            setThatProp( value ) {
                this.$store.commit( 'setMyProperty', value );
            }
        }
    }
</script>

пример использования Actions

<template>
    <div>
        <button @click="doChangeMyProperty(5)">Change me to 5</button>
    </div>
</template>

<script>
    import {mapActions} from 'vuex';
    export default {
        methods: {
            ...mapActions([
                'doAsyncChangeMyProperty',
            ]),
            // Or without helper...
            doThatThing( value ) {
                this.$store.dispatch('doAsyncChangeMyProperty', value);
            }
        }
    }
</script>

двусторонний биндинг

<template>
    <div>
        <input type="text" v-model="my_property"/>
        {{ my_property }}
    </div>
</template>

<script>
    export default {
        computed: {
            my_property: {
                get() {
                    return this.$state.getters.my_property;
                },
                set( value ) {
                    this.$state.dispatch('setMyProperty', value);
                }
            }
        }
    }
</script>

On Store Object

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        my_property: 47
    },
    getters: {
        getMyProperty: state => {
            return state.my_property;
        }
    },
    mutations: {
        setMyProperty: ( state, payload ) => {
            state.my_property = payload;
        }
    },
    actions: {
        doChangeMyProperty: ( context, payload ) => {
            context.commit('setMyProperty', payload);
        },
        doAsyncChangeMyProperty: ( { commit }, payload ) => {
            // Using a timeout, but any async operation can go here
            setTimeout(function () {
                commit('setMyProperty', payload);
            }, 1000);

        }
    }
});

On Modules

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
}

const moduleB = {
    state: { ... },
    mutations: { ... },
    actions: { ... }
}

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
})


store.state.a // moduleA's state
store.state.b // moduleB's state
Ctrl + ↓ Ранее