Pull to refresh
33
Уля@ulechka

ТехЛид iOS, аналитик, DevOps

9
Subscribers
Send message
Об этом и речь: можно написать работающее приложение, если исправить проблемы, которые привносит кроссплатформенная разработка. У большинства из них есть решения, да, но какой смысл решать проблемы, когда можно провести время за более приятным занятием, например, реализуя удобную фичу для пользователей.
Решение добавить еще один уровень обработки событий только сильнее отдаляет пользователя от желаемого действия. На флагманах, конечно, это будет не очень заметно, а на остальных устройствах — пользователи останутся недовольны.
Мы с него ушли довольно давно. Тогда на проекте мы собрали много глюков интерфейса, с большинством из которых сумели справиться. Проблемы были в основном от сырых библиотек, возможно, с ними сейчас получше. Главная причина, по которой ушли — это полностью нерабочее приложение на больших объемах данных. Т.е. пока тестировали — все было хорошо, как только попробовали загрузить реальные данные — приложение зависло.
Недавно видели чужое приложение на Phonegap, которое нам предложили доделать. Первая проблема, которая бросилась в глаза сродни проблемы дабл-кликов: по нажатию на кнопку в приложении, открывается новый экран и на нем срабатыает то же самое событие, если там тоже кнопка на этом месте — то вызывается обработка нажатия на нее, и так далее, как будто клик проходит сквозь экраны.

Главная проблема Phonegap, на мой взгляд, это снижение скорости реакции по сравнению с нативными приложениями. Если в нативном приложении вы хотите запустить камеру, или выполнить любую другую стандартную функцию операционной системы — вы просто делаете соответствующий вызов. И функция исполняется настолько быстро, насколько это позволяет устройство и операционная система. В phonegap вызов должен быть пропущен из веб-котента в Cordova, а оттуда попадет в систему, где и будет обработан нативными средствами.

Вполне допускаю, что подобные технологии могут заинтересовать тех, кто делает свое первое мобильное приложение, и еще не знает к чему стремиться, и как круто можно сделать натив. Может заинтересовать веб-разработчиков, которые хотят сделать какое-то несложное приложение. Но проблемы останутся те же, что и на многих кросплатформенных приложениях: вы связаны проблемами самой системы, вы все время ждете обновлений библиотеки, когда новая платформа уже на рынке, и ваши пользователи все время ждут. И каждый раз, когда у вашего приложения проблемы — будь то зависания, глюки, неспособность работать с большими данными или устаревший дизайн — вы теряете пользователей, имидж и, в конечном счете, деньги.
от автора статьи:

Статья вовсе не о том, как проектировать вьюконтроллеры, а о том, как не поиметь проблем от неосторожного использования KVO.
Тем не менее, я с вами не соглашусь, и подробно объясню, почему.
По ссылке написано только что «view objects are typically decoupled from model objects». «Обычно отделены» не значит, что их всегда необходимо отделять (иначе что?).
Если не ограничиваться схоластикой, а посмотреть на практические следствия использования конкретных наследников UITableViewCell не только как наследников UIView, но и как контроллеров для сопоставляемых им модельных объектов, то имеем вот что:
  1. Конкретные классы ячеек (так же, как и вьюконтроллеров) зачастую проектируются под конкретные модельные классы: если у вас есть ячейка с лэйблами, однозначно сопоставленными атрибутам конкретного модельного класса, то говорить о переиспользуемости или независимости такой «вьюхи» от вашей модели (а это главная причина отделения view от model) не приходится.
  2. Даже если вы можете представить себе сценарий, где какая-нибудь ячейка с полями «Фамилия», «Имя», «Отчество» будет переиспользована для представления разных модельных объектов в разных приложениях или частях одного приложения, то это можно успешно реализовать, объединив модельные классы общим протоколом (это можно сделать и в категориях), и имея в ячейке ссылку на модельные объекты, типизированную только протоколом. Если же вы не планируете ее так переиспользовать, то зачем усложнять себе жизнь?
  3. Название класса ETRDocumentCell как бы намекает на класс ETRDocument. Если бы ячейка не имела к нему отношения, ее следовало бы назвать ETRTableViewCellWithALabelAndAStarShapedButton, что бы в точности отражало ее суть. Без шуток.
  4. UIViewController как таковой не имеет отношения к модели. Он, конечно, называется контроллером, но в своей базовой реализации он контролирует вовсе не модель, а свою вьюху и другие вьюконтроллеры. В конкретных реализациях он имеет то же право работать с моделью, что и ячейки, или любые другие пользовательские реализации классов, имеющих непосредственное отношение к слою View. И критерий здесь не только в наличии класса UIView среди предков.
  5. Нетривиальные операции с моделью должны делаться не во вьюконтроллерах, а в классах-контроллерах, не имеющих к View никакого отношения вообще. Только так они будут переиспользуемы и независимы. Чтение значений атрибутов в этом смысле операция тривиальная.
  6. При работе с UIKit существует негативная тенденция к перегрузке вьюконтроллеров различными функциями (см. Massive View Controller, http://www.objc.io/issue-1/, http://doing-it-wrong.mikeweller.com/). Вынося из них любую логику, программист совершает «Добро».
  7. Только ячейка должна знать, какие у нее есть сабвьюхи, и как на них ложатся атрибуты модельного объекта. Имея эту логику снаружи ячейки, мы нарушаем ее целостность и инкапсуляцию, разносим знание о ее внутреннем устройстве по большему числу мест в проекте, и вообще творим «Зло».
  8. Вынося из UITableViewController в ячейку логику по отображению модельного объекта, можно полностью избавить вьюконтроллер от знаний об отдельных объектах. То есть вьюконтроллер работает со списком, а ячейка — с его элементами. Чем не single responsibility principle?
  9. Имея непосредственную привязку ячеек к модельным объектам, гораздо проще реализовывать любую асинхронную логику. Например, показывать прогресс бар в ячейке, соответствующей какой-нибудь загрузке. Если эта логика будет во вьюконтроллере, она будет содержать вложеннные условия и циклы с indexPath'ами и прочие радости. Да и тот же KVO по сути является такой асинхронной логикой. Можете для сравнения реализовать весь пример «по-вашему», и посмотреть, что будет аккуратнее. Вам придется либо всегда наблюдать за всеми документами, либо каким-то неочевидным образом отслеживать, для каких из них существуют ячейки. Среднестатистический программист, начав по-вашему, скорее всего сделает одну нотификацию, по которой будет делать [self.tableView reloadData], и прощай выделение ячеек, анимации, плавный скролл и так далее.
  10. Даже reloadRowsAtIndexPaths потенциально может иметь нежелательные последствия. Да и нужно-то всего лишь поменять selected у UIButton.
  11. Имея непосредственную привязку ячеек к модельным объектам, гораздо проще обрабатывать user interaction. Нажатие кнопок в ячейке может обрабатываться самой ячейкой без усложения вьюконтроллера. Да и в prepareForSegue:sender: не нужно никаких получений indexPath по ячейке с доставанием модельного объекта по нему.
  12. Я уже давно использую этот паттерн во всех ячейках, и никогда не имел от этого никаких проблем, а имел один только вышеперечисленный профит, включая вьюконтроллеры не больше 250 строк. Поэтому считаю, что имею право его всем рекомендовать.
Если не хочется писать пароль в файл, а это проще для начинающих, можно внести в файл sudoers строчку
username ALL=NOPASSWD: /usr/bin/xcode-select

В нашем случае:
jenkins ALL=NOPASSWD: /usr/bin/xcode-select

но если доступ к jenkins ограничен, то можно использовать и файл, увидеть его содержимое можно только если есть доступ к Jenkins или собственно к машине с Xcode.
А мы читали вашу статью :)
У нас похожий способ генерации страничек, выращенный из iOSBetaBuilder, но мы в статье делали упор на два Xcode — в преддверии так сказать :) ну и в целом инструкция — вещь полезная.

Еще недавно находили идею — сделать мобильное приложение для получения Push-уведомений, и с Jenkins слать ссылки на него. Мне кажется, пуши лучше подходят для тестировщиков, письма — для менеджеров и заказчиков.

Но это тема для отдельной статьи.
Можно
Можно в общем шаблоне прописать ссылку с параметром, например mydomain.ru/${JOB_NAME}/index.html

А можно для каждой отдельной задачи в Jenkins под кнопкой Advanced для каждого триггера поменять шаблон — например, на успешную сборку слать ссылку, а на сломанную — нет.
Олежка, если бы мы
выкатили готовую коробку вида «скачай, распакуй, пропиши группы в контакте и в фейсбуке — и на всех сотовых компании новейший фидер»
, мы бы сделали еще один кусок опенсорса и тот, кто взялся бы прописывать группы в контакте и в фейсбуке нашел бы что не все сделано так, как он хочет, и все равно говорил бы, что усе плохо.

Хммм, а почему вся эта красота лежит на хабре, а не во внутреннем уютном бложеге?

А кто сказал, что она не лежит в уютном бложеке? =)
Вообще, она лежт на хабре, потому что нам интеерсно мнение потенциальных пользователей о таком приложении: что было бы интересно добавить, что подразукрасить, какие возможности подключить.

Ну и вообще говоря, есть очучение, что система эта довольно слабо кастомизируема. Для одной фирмы можно классно всё на шурупы прикрутить, а дальше будет печальнее.

А дальше будут шурупы для другой фирмы.
Это какой-то холиварный поинт кастомайзить на уровне пользователя или на уровне разработки: мы — за разработку, ты — вроде за опен-линух-путь. Мы предполагаем, что большинство наших пользователей просто возьмут и будут наслаждаться удобством, а не «о, какой интересный конструктор», поэтому мы не планируем давать шурупы конечным пользователям.
Ну нет… Суть как раз в том, что это линия наших событий. Там ведь не только записи с социальных сетей.

Насчет стилистики и дизайна замечание спорное, мы цветами выделяем разные разделы приложения, а основной стиль оформления везде одиаковый. Я думаю, тут каждая компания может выбрать что-то для себя.
Замечание под номером два — меня аж вдохновило :) Обязательно так и сделаем

Третье — очень спорное. С одной стороны экономить место на экранах мобильников — это хорошо и правильно, но и сильно плотно размещатть информацию — неудобно для восприятия. Возможно, что-то мы еще соптимизируем с местом, но пока кажется, что текущее решение — наиболее подходящее для выражения идеи Timeline и легкости интерфейса.
Фильтр событий? Например я в какой-то команде и мне плевать что там происходит у заокеанских друзей или в головном офисе и хочу читать только фид относящийся непосредственно к моему подразделению/офису в моем городе/etc. Есть такая возможность?


Да, об этой возможности мы подумали. Мне кажется, наиболее удобный вариант — это пользовательские настройки, которые позволяют выбирать, какие именно типы событий пользователь хочет видеть в таймлайне. Но к этому добавится еще и поиск по типам и, наверное, по времени, и просто по тексту.

Оповещения о срочных делах/изменениях?


Для подобного функционала необходимо добавить поддержку событий из баг-трекера или другой системы ведения проекта. О подобной возможности мыслей не было. Мы больше работали в направлении объединяющей социальной инфрастуктуры, нежели инструмента для работы.

Опять же, те сообщения, которые относятся к конкретному человеку/подразделению в такой фид-агрегатор не попадут (или я не правильно понял мысль?) и все-равно надо либо использовать другие методы взаимодействия, либо создавать аккаунты для этого приложения на каждого пользователя чтобы через него как-то взаимодействовать с конкретными людьми.


В приложении есть система авторизации, но она пока доступна только сотрудникам компании. Можно добавить любой тип событий, будь то форум, или private messages или чаты, можно создать «болталки» на каждую команду или отдел. Вопрос в том, что будет более полезно? У нас возникла идея — мы сделали базовое приложение, а теперь нам нужны отзывы: с такой системой, которая умеет показывать любые события, оповещает пользователя и дает доступ ко внутренним ресурсам компании — можно сделать любое приложение от иструмента командной работы до корпоративной социальной сети, и вариант про саппорт тоже очень органично ложится на эту основу.

Как вы собираетесь балансировать между сложной/дорогой разработкой(богатый функционал и прочее) и очередной свистоперделкой (если человек пользуется ФБ или ВК и у него есть для этого приложение, зачем ему еще одно, которое дублирует функции первого?)


Ну, не делать то, что уже есть :) Например, у нас есть список контактов, но все виды коммуникаций: емейл, смс, скайп, звонок и т.п. используют стандартные приложения. Наше приложение не собирается стать мульти-клиентом социальной сети, мы показываем события компании из самых разных источников.
Просто ведь во всех соцсетях сидеть не будешь, и новости о компании тоже не под копирку расходятся по разным уголкам интернета, а компания растет, и появляются новые люди, и новые проекты, и становилось все сложнее быть в курсе. Вот нам и захотелось сделать приложение, которое будет нас всех объединять. К тому же это удобно и для наших портнеров, и для соискателей, — для всех тех, кто интересуется нашей жизнью и работой :) Долго придумывали интерефейс, в котором можно собрать разнородную информацию, отражающую происходящие у нас события — и остановились на таймлайне: все события показываются в порядке их создания.

Ну а для сотрудников компании, конечно же, доступно больше функций, и информация, которая не может быть открыта посторонним, доступна только после авторизации.
12 ...
7

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Registered
Activity

Specialization

Mobile Application Developer
Lead
Git
iOS development
MVVM
Client-server applications
Coredata
Fastlane
Objective-C
SWIFT