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

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Пишем скрипты на 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