Git Hub
коротко
90 заметок с тегом

Swift

Итерация по enum

6 ноября, 19:49
enum State {
    case none
    case one
    case two
}

Конформим State под протокол CaseIterable

extension State: CaseIterable {}

После этого мы можем итерироваться

State.allCases.forEach {
    print($0)
}
Swift

Интересные Callback'и

13 августа, 21:41

Объявляем тип для callback замыкания

typealias RegStateCallbackType = @convention(c) (_ accountId: pjsua_acc_id) -> Void
var onRegStateCallback: RegStateCallbackType?

И можно тогда заюзать следующим образом

endpointCfg.cb.on_reg_state = onRegStateCallback
C   Swift

Swift String to C char *

14 июня 2019, 0:51
void mi_connect_device(char *device_name);
func connect(to device: String) {
        device.withCString {
            let int8Pointer = UnsafeMutablePointer<Int8>(mutating: $0)
            mi_connect_device(int8Pointer)
        }
    }
C   Swift

RxSwift кастомная View'ха

7 марта 2019, 4:03

Пишем своё расширение кастомной вьюхи.

import UIKit
import RxSwift
import RxCocoa


class CustomView: 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: CustomView {
    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)

RxSwift   Swift

Login screen

1 марта 2019, 15:03

Реализовал Login screen на VIPER, хотя в несколько облегчённом варианте, скорее всего ещё допилю взаимодействие между модулями. Router — > Router + Presenter

Мои исходники

VIPER
V — View (Views + ViewControllers)
I — Interactor — бизнес логика модуля
P — Presentor (ViewModels and prepare)
E — Entities — (Models)
R — Router

Swift   VIPER

Swift KVO

21 января 2019, 23:25

Модель

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
KVO   Swift

Swift: setTimeOut

13 января 2019, 1:52
DispatchQueue.main.asyncAfter(deadline: .now() + 0.600) {
     // some code
}
Swift

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  "--:--"
    }
Swift

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
    }
}
Swift

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()
Swift

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.

Swift

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

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

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

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

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

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
RxSwift   Swift

Статья о lldb

24 сентября 2017, 17:47
Debug   Swift

Хранимые переменные в экстеншенах

4 сентября 2017, 12:53

Stored properties in swift extensions

protocol PropertyStoring {
 
    associatedtype T
 
    func getAssociatedObject(_ key: UnsafeRawPointer!, defaultValue: T) -> T
}
 
extension PropertyStoring {
    func getAssociatedObject(_ key: UnsafeRawPointer!, defaultValue: T) -> T {
        guard let value = objc_getAssociatedObject(self, key) as? T else {
            return defaultValue
        }
        return value
    }
}
 
protocol ToggleProtocol {
    func toggle()
}
 
enum ToggleState {
    case on
    case off
}
 
extension UIButton: ToggleProtocol, PropertyStoring {
 
    typealias T = ToggleState
 
    private struct CustomProperties {
        static var toggleState = ToggleState.off
    }
 
    var toggleState: ToggleState {
        get {
            return getAssociatedObject(&CustomProperties.toggleState, defaultValue: CustomProperties.toggleState)
        }
        set {
            return objc_setAssociatedObject(self, &CustomProperties.toggleState, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
 
    func toggle() {
        toggleState = toggleState == .on ? .off : .on
 
        if toggleState == .on {
            // Shows background for status on
        } else {
            // Shows background for status off
        }
    }
}
 
let a = UIButton()
print(a.toggleState)
a.toggleState = .on
print(a.toggleState)

Источник: https://marcosantadev.com/stored-properties-swift-extensions/

Swift

Жизненный цикл SpriteKit

18 августа 2017, 11:46
SpriteKit   Swift

RxAlamofire + SwiftyJSON

27 июля 2017, 19:40
import RxAlamofire
import SwiftyJSON

    func load() {
        let host = "http://chemnote.ru/api/v1/periodic/"
        guard let url = host.url else { return }
        RxAlamofire.requestJSON(.get, url)
            .bind { (r, json) in
                let dic = JSON(json)
                for (_,element) in dic {
                    let symbol: String = element["symbol"].stringValue
                    PeriodicTable.elements.append(Element(with: symbol))
                    print("el: \(symbol) ")
                }
            }
            .disposed(by: bag)
        
        
    }
Swift

md5 на swift

24 июля 2017, 18:22
import CryptoSwift

extension String {
    
    func md5() -> String {
        let bytes:Array<UInt8> = Array(self.utf8)
        let md5hash = bytes.md5().toHexString()
        return md5hash
    }
    
}
Swift

Debug constraints

22 июля 2017, 12:41
Debug   Swift

Printable

17 июля 2017, 14:12
extension Element: CustomStringConvertible {
    var description : String {
        return "element: \(symbol)"
    }
}
Swift
Ctrl + ↓ Ранее