Arm1.ru

Модальный UIVIewController с прозрачностью

Шпаргалка - как запрезентить UIViewController поверх другого так, чтобы он был полупрозрачный и под ним просвечивал контент.

Выставляем в Storyboard для Segue поле Kind как "Present Modally". Для UIViewController, который показываем, выставляем цвет фона Clear Color, делаем внутри фон (картинка или другой UIView) со значением alpha, например, 0.5.

В коде:

self.performSegueWithIdentifier("segueName", sender: self)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  if segue.identifier == "segueName" {
    let vc = segue.destinationViewController as! YourViewController
    vc.modalPresentationStyle = .Custom
  }
}

 

comment comments

Редизайн блога

Решил поизучать, как выглядят сайты в Material Design от Google. Нашёл у них библиотеку Material Design Lite и запили его на сайт. Стало читабельнее, вроде, и из коробки адаптивный дизайн, можно читать с мобилок, да и на ретине выглядит теперь сочнее. Удобно, когда из готовых кусков можно собрать то, что тебе нравится. Результат мне нравится больше, чем то, что можно наваять, например, на Twitter Bootstrap.

Долго думал над шапкой и в итоге с любовью спёр идею у Apple с их страницы, посвящённой WWDC '16 :) запили на SVG и анимировал курсор на JS (правда, только на десктопной версии). Смотрел на Polymer, но что-то оно как-то не завелось у меня сходу, да и уже на MDL многое сделал. Идея веб-компонентов, конечно, классная, и семантически круто выглядит, но пока отложу её до более хорошей поддержки браузерами. Как-то там, есть ощущение, что всё сильно на Node.JS завязано, а переписывать его на ноду мне уже не хочется, жду новых релизов Swift, чтобы на него  переписать. 

comment comments
local_offer бложек

Тестирование асинхронного кода в XCTest

Пока писал тесты в приложении, столкнулся с тем, что не работают тесты, в которых есть асинхронный код. Например, если мы делаем асинхронный запрос в сеть и callback-блоке проверяем то, что получилось. Проверки просто не выболнялись и Xcode говорил, что тест удачно пройден, даже если он заведомо не должен пройти. 

В ходе гугления оказалось два решения - одно через семафоры из Grand Central Dispatch, воторое с помощью expectations. С expectations мне понравилось больше. Пример теста:

import XCTest

class apiClientTests: XCTestCase {
  override func setUp() {
    super.setUp()
  }

  override func tearDown() {
    super.tearDown()
  }

  /**
  SampleTest
  */
  func testSampleAsyncRequest() {
    let exp = expectationWithDescription("\(#function)\(#line)")

    APIClient.sharedInstance.someMethod { (responseObject, error) in
      XCTAssertNotNil(responseObject, "responseObject should not be nil")
      XCTAssertNil(error, "error should be nil")

      exp.fulfill()
    }

    waitForExpectationsWithTimeout(40) { (error) in
      if error != nil {
        XCTAssertTrue(false)
      }
    }
  }
}

comment comments

Про использование Swift на сервере

Начал пробовать использовать Swift на сервере для бэкенда. Если с макосью всё довольно понятно в плане как начать использовать Swift (да хотя бы тот же Xcode), то с Linux не так всё очевидно оказалось.

На сайте Swift.org есть инструкция для OS X и для Ubuntu (14.04 и 15.04). Сразу обрадовался, что они выкладывают уже скомпилированные бинарники. Вкратце - скачиваем архив, скачиваем всякие ключи и подписи, проверяем подпись архива на всякий случай, распаковываем архив и делаем export чтобы из консоли можно было выполнить команду. Например

swift --version
Swift version 2.2.1-dev (LLVM da67bff217, Clang 81d0486fb2, Swift 82adb8fc96)
Target: x86_64-unknown-linux-gnu

Начинаем какой-нибудь простой Hello World - просто создаём проектик, который в консоль выводит текст, что-то вроде:

import Foundation

print("hello world")

Далее надо проверить - работает ли оно. Выполняем:

swift build
error: unable to invoke subcommand: /home/webserver/swift-2.2.1-SNAPSHOT-2016-04-23-a-ubuntu14.04/usr/bin/swift-build (No such file or directory)

Сюрприз! В релизную версию Swift версии 2.2.1 не включён swift-build. То есть собрать проект релизной версии мы не можем. Слегка офигеваешь от этого. Гуглишь - оказывается, надо дев-версию Swift скачивать. А это предрелизная версия Swift 3.0.

В ней всё есть, проект собирается, бинарник запускается и выводит текст в консоль. Но как-то это странно, что туториал с сайта не работает на релизной версии. Хотя пишут, что в предыдущих релизах он был.

Самое грустное - что пока даже сетевые запросы нельзя слать из опенсорсного Swift - в Foundation не реализован NSURLRequest, значит мои мысли о том, чтобы юзать CouchDB через его REST API пока можно отложить. И на гитхабе пока красуется надпись в описании текущего состояния Swift: 

NSURLSession and related classes are not yet implemented.

Можно, конечно, сишные библиотеки использовать. Например, IBM используют обёртку на CURL под названием CCurl. Но хочется как-то из коробки, средствами языка. Поэтому, пожалуй, подожду, когда это наконец сделают.

Мои ковыряния с web-фреймворком Swift Express показали, что сделать на нём сайт или REST API можно. Я вчера вечером даже сделал заготовку для переписывания этого блога - готовы шаблоны, роутинг, выводится всё оформление сайта, осталось подставлять данные из базы данных. И теперь стоит вопрос - как доставать данные из базы. Есть обёртки над сишными библиотеками для MySQL и MongoDB, но мне вот всё хочется продолжать использовать CouchDB, раз уж я им итак пользуюсь во многих проектах. А у него REST API, то есть доставать данные надо через сетевые запросы, которые в Foundation пока не завезли, а использовать сторонние инструменты как-то не хочется, потому что потом, когда всё реализуют, будет логичнее перейти на встроенные инструменты, то есть придётся выпиливат. Подожду пока с переписыванием своего бложека на Swift :)

comment comments
local_offer swift ubuntu

Заметка про Socket.IO-Client-Swift

Небольшая шпаргалка - для socket.io есть клиент на Swift. Казалось бы, на гитхабе хорошо расписано, как его использовать. Вот только к моему бэкенду на Node.js он никак не хотел подключаться с кодом примеров.

Логи показывали (если пробовать через polling-запросы), что клиент стучится по адресу /engine.io и получает 404 ошибку. Изучение браузерной Javascript-библиотеки, которая с этим же бэкендом работает без каких-либо танцев с бубном, показало, что надо указать другой путь - /socket.io. Благо, для этого есть специальная опция.

Итого, получаем:

let socketURL = NSURL(string: "http://localhost:3000")
let socket = SocketIOClient(socketURL: socketURL!, options: [
  .ForceWebsockets(true),
  .Path("/socket.io/"),
  .ConnectParams(["token": "token"])
])

socket.on("connect") {data, ack in
  print("socket connected")
}

socket.connect()

comment comments

App Store Release Informer 1.1.0

Переписал своего бота на ES2015, плюс добавил тесты. Когда бот пишет о том, что вышла новая версия в App Store, то пишется и что нового в этой версии.

Исходники на GitHub.

comment comments

Carthage vs. CocoaPods

Пара мыслей о Carthage в сравнении с CocoaPods.

Что у Carthage так же, как и у CocoaPods:

  • Для CocoaPods создаётся Podfile. Для Carthage нужно создать Cartfile.
  • И там, и там можно указать конкретную версию зависимости и конкретный git-репозиторий.
  • После установки зависимостей создаётся Podfile.lock для CocoaPods и Cartfile.resolved для того, чтобы установить конкретные версии зависимостей/библиотек.
  • И для CocoaPods, и для Carthage довольно просто всё устанавливается одной командой из консоли. 

Минусы:

  • Все зависимости необходимо добавлять ручками в проект и раздел Build Phases. Делается это один раз, но ручками, в отличие от CocoaPods, где он сам генерит WorkSpace. С одной стороны это неудобство, с другой - просто мы избалованы CocoaPods. Например, в мире Node.js мало сделать npm install package, ты всё равно должен заинклудить зависимость там где надо через require.
  • Меньше выбор. Меньше популярности. CocoaPods старше, популярнее и многие библиотеки распространялись через CocoaPods. Многие до сих пор только через них распространяются, включая, например, SDK от Google. Для Carthage проще найти что-то более менее свежее. Зато оно, как правило, доступно и через CocoaPods, и через Carthage, и даже через Swift Package Manager.

Плюсы:

  • Зависимости билдятся один раз. При любой сборке проекта библиотеки и зависимости не собираются заново, даже если очистить все кэши и сделать все clean'ы. В итоге каждый билд идёт быстрее.
  • Не создаётся ещё одного файла .xcworkspace, файл проекта остаётся нетронутым. Создание WorkSpace в последних версиях CocoaPods глючит уже чуть ли не полгода и создаёт этот WorkSpace так, что проект просто не собирается и приходится лезть ручками что-нибудь исправлять. Например, путь для поиска файлов-заголовков.
  • При обновлении зависимости до последней версии, опять же, не трогается файл проекта. Просто пересобираются, они уже добавлены в проект.
  • Можно сбилдить зависимость сразу для всех платформ, или для конкретной, например, для tvOS.
  • У CocoaPods центральный репозиторий. Если он упадёт - ничего не будет работать. У Carthage такого нет, он просто берёт с GitHub зависимости. С одной стороны это тоже некий центральный репозиторий, но без промежуточного звена, и шансы, что он выстоит от нагрузки, выше.

 

comment comments
local_offer carthage cocoapods xcode