?

Log in

No account? Create an account

Previous Entry | Next Entry

Swift, Apple Watch, and dynamic Graphs

Поробовал я попрограммировать под Apple Watch на досуге. На Swift'е. Свифт очень даже ничё так. Похож на OCaml чем-то. Например, константы определяются через let, переменные через var. Но константы дутые: внутри них можно менять всё, что там меняется.

Swift, определённо, шаг в правильную сторону. Программировать было, в основном, приятно. Впрочем, XCode традиционно раздражал своими тормозами и подсказками.

Сделал приложение, которое показывает динамический график, движущийся со плавностью в 30fps в эмуляторе. Заодно разобрался, как сделать так, чтобы анимированные гифки были с нормальными цветами, а не все в дизере. Для этого надо сначала со всех кадров собрать палитру, затем её в дальнейшем и использовать. В итоге workflow выглядит так: обычным QuickTime'ом делается скринкаст, затем обрабатывается скриптом, делающим из .MOV → .GIF.



Исходники приложения здесь: https://github.com/vlm/ExampleWatchGraph (см. в сторону WatchKit Extension — это именно то, то выполняется на часах).

Проблема с часовым API заключается в том, что там всё через ж всё в Apple-стиле. Например, чтобы нарисовать что-то динамическое на экране, надо 30 раз в секунду:
  1. Создать графический контекст заданного заранее размера. Потому что вычислить размер WKInterfaceImage, в который вставлять будешь получившийся битмап, нельзя. Размер интерфейсного элемента можно задать (set), но не опросить (get).
  2. Нарисовать, что нужно, через CoreGraphics (Quartz 2D) — это лёгкая часть.
  3. Превратить контекст в .PNG, и уже этот .PNG разместить на WKInterfaceImage. См. здесь: https://github.com/vlm/ExampleWatchGraph/blob/master/ExampleWatchGraph%20WatchKit%20Extension/GraphPainter.swift#L117


В итоге вся батарейка на часах тратится на то, чтобы эти .PNG запаковывать и распаковывать. Как только Apple сообразит, как этого избежать, часы начнут работать неделю от аккумулятора.

Ну или я что-то не понял.

Comments

( 15 comments — Leave a comment )
eugene_ivanov
Dec. 2nd, 2015 07:44 pm (UTC)
ужыс
demmonoid
Dec. 2nd, 2015 09:06 pm (UTC)
Маркетинговый ход же. А потом новым релизом WatchOS ВНЕЗАПНО увеличат время жизни батареи в разы.
lionet
Dec. 3rd, 2015 08:07 am (UTC)
Надеюсь!
levgem
Dec. 3rd, 2015 01:52 am (UTC)
ты меня сейчас ужаснул просто. Почему примитивное рисование вызывает такие бешеные проблемы?
lionet
Dec. 3rd, 2015 08:21 am (UTC)
Потому что в WatchOS 1.0 этот компонент, который занимается управлением тем, что происходит на экране, работал вообще на телефоне. И передавал данные телефону в виде сериализованной фигни, а-ля "вот тебе картинка, отобрази в своём плейсхолдере, и вот сюда ещё добавь кнопку с такими-то размерами". А часы всё это отображали.

В качестве артефакта такого подхода остались показ картинок через промежуточную сериализацию, и отсутствие возможности понять координату клика — координаты отлавливаются часами и превращаются в аналог Button1Pressed-эвентов.

P.S. Это спекуляции, но таково моё текущее впечатление от экосистемы.
develop7
Dec. 3rd, 2015 09:26 am (UTC)
потому, что когда что-то достигается без страданий и унижений, хипсторы воротят нос
prepor
Dec. 3rd, 2015 08:14 am (UTC)
У меня к свифт два вопрос, один риторический, на другой я ожидаю когда-нибудь получить ответ :)

1. Никаких советов / ответов про concurrency
2. В языке полно вещей, позволяющих делать плохое: force unwrapping, force downcasting, даже implicit force unwrapping. Если любая из этих операций таки привела к плохому, наряду с такими традиционными штуками как деление на ноль и выход за пределы массива, то программа просто падает, без всякой возможности как-то словить и обработать. Как с этим жить?
nnknows
Dec. 3rd, 2015 09:50 am (UTC)
Извиняюсь за тупой вопрос, но откуда следует, что сериализуется-десериализуется в PNG. UIGraphicsGetImageFromCurrentImageContext должна же просто оборачивать private массив raw-точек из context в более-менее public UIImage со сбросом очереди на рисование (если есть) и, возможно, с обычным копированием.

Edited at 2015-12-03 09:52 am (UTC)
lionet
Dec. 3rd, 2015 04:39 pm (UTC)
Это прекрасный вопрос! Не смог удержаться, и сделал двухминутный скринкаст по этому поводу:


blackyblack
Dec. 3rd, 2015 06:49 pm (UTC)
Вот это я понимаю, человек ответственно к делу подошёл... Может там в потрохах где-то есть шорткат, чтобы сразу распакованный битмап загрузить или вектор?
lionet
Dec. 4th, 2015 03:17 am (UTC)
Я не нашёл на стековерфлоу, просмотрев watchkit sdk документацию, и спросив в твиттере.
nnknows
Dec. 3rd, 2015 09:09 pm (UTC)
Спасибо! При Джобсе такого не было =)
lionet
Dec. 4th, 2015 03:18 am (UTC)
Воистину, не было.
vzaliva
Dec. 4th, 2015 06:52 pm (UTC)
Жаль что ты все это пишешь на русском. Хотел перепостить ссылку но большинство моих знакомых кому это было бы интересно по русски не поймут :(
( 15 comments — Leave a comment )

Profile

lionet
Lev Walkin
Website

Latest Month

December 2016
S M T W T F S
    123
45678910
11121314151617
18192021222324
25262728293031
Powered by LiveJournal.com
Designed by yoksel