Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Пишем скрипты на Swift

Пишем скрипты на Swift

Avatar for Ruslan Kavetsky

Ruslan Kavetsky

December 06, 2019
Tweet

More Decks by Ruslan Kavetsky

Other Decks in Programming

Transcript

  1. Реальность ! @interface PromoModel: NSObject <NSCoding> @property (nonatomic, readonly, copy,

    nonnull) NSString * name; @property (nonatomic, readonly, strong, nullable) NSURL * pictureUrl; @property (nonatomic, readonly, assign) NSInteger amount; - (nonnull instancetype)initWithName:(nonnull NSString *)name pictureUrl:(nullable NSURL *)pictureUrl amount:(NSInteger)amount; @end static NSString *const kPromoModelName = @"PromoModel.name"; static NSString *const kPromoModelPictureUrl = @"PromoModel.pictureUrl"; static NSString *const kPromoModelAmount = @"PromoModel.amount"; @implementation PromoModel - (nonnull instancetype)initWithName:(nonnull NSString *)name pictureUrl:(nullable NSURL *)pictureUrl amount:(NSInteger)amount { self = [super init]; if (self) { _name = [name copy]; _pictureUrl = pictureUrl; _amount = amount; } return self; } - (nullable instancetype)initWithCoder:(NSCoder *)decoder { self = [super init]; if (self) { _name = [decoder decodeObjectForKey:kPromoModelName]; _pictureUrl = [decoder decodeObjectForKey:kPromoModelPictureUrl]; _amount = [decoder decodeIntegerForKey:kPromoModelAmount]; } return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:_name forKey:kPromoModelName]; [coder encodeObject:_pictureUrl forKey:kPromoModelPictureUrl]; [coder encodeInteger:_amount forKey:kPromoModelAmount]; } @end 5
  2. Вы уже его знаете ! • Знакомое API Foundation, URLSession,

    FileManager, etc • Привычные инструменты Xcode, Instruments • Меньшее переключение контекстов Тут Swift, там Swift 12
  3. !"# • Меньший бас фактор для скриптового кода • Проще

    поддерживать • Меньше зависимостей от других языков 14
  4. А зачем это мне? ! • Новые классы и библиотеки

    • Любая архитектура и другие подходы • Не продакшен код • Можно писать в VIM или блокноте • Не надо верстать вьюшки ! 15
  5. Технические плюсы • Быстрый ⚡ • Статическая типизация " •

    Современный синтакс # • Open Source, но поддерживается Apple 16
  6. Я не знаю Swift ! • Отличный способ начать писать

    на нём • Можно учить язык без привязки к платформе и операционной системе • Первые шаги в сторону iOS разработки 17
  7. Динамические фреймворки Имеют расширение .framework Подключаются через флаг -F Для

    исходного кода $ swift -F Frameworks myScript.swift Можно запустить REPL с дополнительными фреймворками $ swift -F Frameworks 30
  8. Динамические фреймворки Имеют расширение .framework Для скомпилированного скрипта добавляем путь

    к фреймворкам через утилиту install_name_tool $ install_name_tool \ -add_rpath "@executable_path/../Frameworks/" \ myScript ../Frameworks — относительный путь к папке с фреймворками myScript — исполняемый файл скрипта 31
  9. Статические библиотеки Имеют расширение .a • Код библиотеки копируется в

    исполняемый файл во время компиляции • Чтобы правильно собрать скрипт, понадобится Xcode 33
  10. // swift-tools-version:5.1 import PackageDescription let package = Package( name: "Script",

    dependencies: [ .package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.0") ], targets: [ .target( name: "Script", dependencies: ["Alamofire"]) ] ) 37
  11. Команды Обновляем зависимости $ swift package update Запускаем $ swift

    run Собираем $ swift build Генерируем Xcode проект swift package generate-xcodeproj 38
  12. Xcode 11 • File → New → Project → macOS

    → Command Line Tool • File → Swift Packages → Add Package Dependency... 39
  13. #!/usr/bin/swift sh import Foundation import Alamofire // @Alamofire ~> 4.0

    request("ya.ru").response { print(response) } 43
  14. #!/usr/bin/swift sh import Foundation import Alamofire // @Alamofire ~> 4.0

    request("ya.ru").response { print(response) exit(0) } RunLoop.main.run() 49
  15. let url = URL(string: "http://api.slack.com/messages/42") let jsonData = Data(contentsOf: url)

    let message = JSONDecoder().decode(Message.self, from: jsonData) 56
  16. print + fputs struct StderrOutputStream: TextOutputStream { mutating func write(_

    string: String) { fputs(string, stderr) } } var standardError = StderrOutputStream() print("Error!", to: &standardError) 67
  17. FileHandle let errorFileHandle = FileHandle.standardError let error = "Something went

    wrong" errorFileHandle.write(error.data(using: .utf8)) 68
  18. try shellOut(to: "mkdir", arguments: ["~/Projects/Scripts"]) try shellOut(to: "mkdir Scripts", at:

    "~/Projects") try shellOut( to: [ "mkdir ~/Projects/Scripts", "cd ~/Projects/Scripts", "touch script.swift"]) 73
  19. Готовые команды ! try shellOut(to: .gitCommit(message: "A scripted commit!")) try

    shellOut(to: .readFile(at: "Podfile")) try shellOut(to: .buildSwiftPackage()) try shellOut(to: .runFastlane(usingLane: "appstore")) try shellOut(to: .updateCocoaPods()) 74
  20. $ swift-objc-gen \ models.txt \ -output Sources/Models • Читаю аргументы

    • Читаю файл models.txt • Генерирую Objective-C код • Записываю код в файлы в папке Sources/Models 77
  21. // beak: kylef/PathKit @ 1.0.0 import PathKit import Foundation ///

    Releases the product /// - Parameters: /// - version: the version to release public func release(version: String) { // implementation here print("version \(version) released!") } /// Installs the product public func install() { // implementation here } 81
  22. $ beak list release: Releases the product install: Installs the

    product $ beak run release --version 1.2.0 version 1.2.0 released! 82
  23. John Sundell Plot DSL язык для генерации HTML, XML и

    RSS Splash Инструмент подсветки синтаксиса Swift TestDrive Возможность попробовать любой фреймворк в одну строчку кода Ink Парсер Markdown файлов 83
  24. Пишите скрипты на Swift • Swift — крутой современный язык

    • Вы и ваша команда его знаете • Начать очень просто • Библиотек много и становится всё больше Руслан Кавецкий @pycuk 84