Arm1.ru

JPG to HEIF converter

JPG to HEIF converter

Today I've decided to experiment with HEIF that was introduced by Apple with macOS 10.13 and iOS 11. They said that it has the same quality with much lower file size.

It's supported in the latest versions of macOS and iOS and last models of iPhone can take pictures in that format.

I'm thinking about compressing my home archive of photos and videos. I was experimenting with HEVC (H.265) and results were great - I had reduced the size of my videos by encoding them to HEVC with an awesome util called HandBrake.

I found the only way to convert JPG to HEIF (which has HEIC extension). It's possible with the Preview app from macOS. But it would be interesting for me if I can do it by myself in Swift. So I did :)

My folder with 64 photos from my action camera was 203 mb in JPG format. And it's only 31.3 mb in HEIC.

macOS and iOS support it from the box. And what's interesting - it's easy to add pictures in this format to the Photos library and it will appear on all your devices that use iCloud. But if you want to export this picture from the Photos library - it will be converted to JPG on the fly, so it looks like you can't export the original HEIC file.

The converter is free and open source (but it's for macOS only): https://github.com/makoni/jpg-to-heif-converter

comment comments

Анимация касания индикатора в UISlider

Анимация касания индикатора в UISlider

Стояла задача - при касании слайдера анимировать в приложении сделать анимированное увеличение ползунка. Так же, как это сделано у Apple в приложениях Apple Music и Podcasts в плеере, когда начинаешь перематывать позицию воспроизведения. Пока искал способ стандартными средствами, убил немало времени. Очень не хотелось писать прям свой кастомный слайдер, хотелось использовать системный UISlider, что мне, в итоге, и удалось.

Читать далее...

comment comments

SMS Антикредит

Надоел мне СМС-спам, который мне периодически приходит - то кредит предлагают, то ипотеку. Как раз, просматривая один из видосов с WWDC, увидел, что Apple дали API для фильтрации SMS-сообщений. Если сработает твой фильтр - то такие сообщения будут приходить без звукового или вибросигнала, втихую, и попадать в отдельную категорию спама в Сообщениях.

Недолго думая, запили такой вот фильтр и выложил в App Store. Надеюсь, кому ещё, кроме меня, пригодится.

comment comments

openssl и Vapor 2

Столкнулся с тем, что перестал компилиться проект на Ubuntu на Vapor 2. Точнее, одна из зависимостей - Crypto. Оказалось, что из-за добавленного репозитория, в котором были более новые версии некоторых библиотек, оно и не компилилось. Запишу сюда - пришлось даунгрейдиться:

apt install libssl-dev=1.0.2g-1ubuntu4.10
apt install openssl=1.0.2g-1ubuntu4.10
comment comments

Benchmarks: Vapor 2 vs. Vapor 1

After migrating my pet project from Vapor 1 to Vapor 2 I've run benchmarks to compare performance. I didn't run benchmarks for the last version of Vapor 1.x which is 1.5.15 so I will compare Vapor 2.1.0 to results of Vapor 1.2.5 that I have from my last results.

My server:

  • 2 GB RAM
  • 1 CPU Core
  • SSD
  • 125 MBPS Out
  • Ubuntu 16.04.2 LTS
  • CouchDB

Benchmark from other server was launched as:

wrk -t4 -c20 -d5m https://my_url

API just gets some data from CouchDB and returns it as JSON. Vapor project has been compiled with Swift 3.1.1.

Читать далее...

comment comments

Weak delegate в Swift 3

Memory usage in Xcode

Боролся тут с утечками памяти в рабочем проекте. Копание привело к тому, что после ухода из UIViewController далеко не вся память освобождается. Если несколько раз открывать этот UIViewController, возвращаться назад и снова открывать - потребляемая память растёт и не очень слабо освобождается.

Суть проблемы оказалась в протоколах и делегатах. Классическая ошибка. У меня в UIViewController используется UICollectionView с кастомной ячейкой, у которой есть делегат. Мой UIViewController является для каждой ячейки делегатом. Пример реализации протокола и делегата в интернете и книге по Swift выгядит примерно так:

// Protocol
protocol MyCollectionViewCellDelegate {
    func someFunc()
}

// UICollectionViewCell
final class MessageCollectionViewCell: UICollectionViewCell {
    var delegate: MyCollectionViewCellDelegate?
}

// UIViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // some code....
    cell.delegate = self
}

Внутри объекта ячейки у нас strong-ссылка ;на делегата (UIViewController), в результате происходит утечка памяти.

Решение простое - сделать слабую ссылку (weak) для delegate. Для этого придётся указать протоколу, что реализовать его сможет только класс. Структуры уже пролетают, но и нужны в структурах нет. Меняется всё так:

// Protocol
protocol MyCollectionViewCellDelegate: class {
    func someFunc()
}

// UICollectionViewCell
final class MessageCollectionViewCell: UICollectionViewCell {
    weak var delegate: MyCollectionViewCellDelegate?
}

После этих простых изменений всё стало прекрасно - после возвращения назад из UIViewController использование памяти возвращается на исходный уровень.

comment comments