Почему передаётся только id, а не сам текст сообщения (зашированный)? Зачем лишний шаг с запросом на сервер? Это должно сильно влиять на скорость работы и особенно на энергоэффективность устройства пользоватея. iOS такие «жадные» service extensions активно ограничивает – не запускает вообще после достижения довольно строгих лимитов.
`NSURLSession` современный, гибкий, высокоуровневый, удобный, документированный, развивающийся API. Не вижу смысла использовать что-то ещё поверх него. Вам реально кажется таким полезным вместо `«POST»` писать `.POST`? Или `.count(5)` настолько лучше, чем `URLQueryItem(parameter: «count», value: «5»)`, несмотря на то, что теперь чтобы добавить новый параметр в вызов, нужно два места в коде менять?
При этом все эти украшательства искусственно ограничивают доступные возможности. Потом эти возможности либо а) не используются б) обрастают дублирующими «своими» API-обёртками.
Вместо просто использования стандартных API, разработчики, приходя на такой проект, вынуждены разбираться в особенностях очередного «фреймворка».
Согласен, это одна из самых важных черт дизайна git. Разобраться со всеми ними не так и сложно, а уровень понимания всей системы и доступные возможности это поднимает колоссально.
Статья полезная в плане понимания, как git работает на более низком уровне, чем обычный пользовательский UI (CLI). Но с практической частью я совсем не согласен – все описанные задачи можно решать обычными, высокоуровневыми командами, т.е. более понятно и наглядно.
1. Синхронизация с другой веткой
Низкоуровневые операции с tree почти всегда можно заменить на обычные манипуляции с ветками. Человеческая версия:
в master могут быть и другие полезные изменения, которые можно не заметить и случайно уничтожить
merge коммиты лучше оставлять "чистыми" – только разрешение конфликтов и никаких логических изменений
лучше просто сделать revert этого изменения перед merge – история будет более понятной и наглядной
6a. Метод rebase через merge — описание
Ну что сказать, хреновый workflow, который заставляет всегда делать rebase. Когда конфликты в ветке "фантомные", это хороший пример, когда нужно делать merge и избежать всех недостатков. Главный из которых – несобирающиеся промежуточные версии.
Зарегистрированные стандартным образом кастомные протоколы вроде как раз в любых конфигурациях NSURLSession работают. protocolClasses как раз для локального расширения отдельной конфигурации.
Но AVPlayer вроде и правда к NSURLProtocol не привязать, хотя бы потому что логика загрузки там нужна более специфичная и сложная, что и видно в API.
Объясните пожалуйста, какую пользу несет возможность динамического выбора языка интерфейса отличного от системного в приложении? Это вызывает сомнение хотя бы потому, что ни Apple, ни абсолютное большинство других разработчиков в своих приложениях так не делают.
Могу подтвердить, что 2k payload поддерживается в iOS7. По крайней мере в sandbox environment такие уведомления приходят и обрабатываются устройством нормально. Более старые версии не проверял, но уверен, что изначально это ограничение только на стороне APNS-серверов Apple. Это также подтверждают и другие источники:
Ну и забыл добавить, что использовать navigation controller для решения такой задачи навигации – это конечно «костыль». И пусть сейчас этот костыль может быть заметен только наметанному взгляду, никто не дает гарантии, что в одной из будущих версий что-нибудь (анимация перехода, взаимодействие с жестами, анимация navigation bar) не изменится так, что результат будет резать глаз даже неискушенному пользователю.
Вся ваша проблема сводится к решению простой задачи – как сделать так, чтобы navigation controller после инициализации из storyboard уже имел два контроллера в стэке. Ваш вариант решения этой задачи обладает принципиальным недостатками:
1. Вы используете -viewDidLoad как место «мгновенного» перехода к следующему контроллеру, хотя это совершенно неподходящее место для выполнения подобных действий – нужно правильно понимать жизненный цикл UIViewController и назначение соотвествующих методов.
2. В вашем случае view первого (Info) контроллера всегда загружается, хотя в большинстве сценариев это бесполезно, т.к. пользователь его никогда не увидит – опять же нужно понимать жизненный цикл контроллера, в частности – когда инициализируется его view.
3. Вы реализуете логику *навигации* внутри отдельно взятого контроллера – это нарушает принятые в системе уровни абстракции. Представьте, что получится, когда вам потребуется показывать Info контроллер где-то в другой части приложения (или например в iPad-версии) – другим способом и в другом контексте навигации.
Есть много вариантов, которые не обладают такими недостатками, а главное – решают задачу на правильном уровне абстракции. В простом варианте можно реализовать соотвествующую логику в AppDelegate:
Часто нет возможности (или желания) наследовать свой контроллер от UITableViewController. Можно конечно создавать временный экземпляр UITableViewController – только для того, чтобы правильно инициализировать UIRefreshControl для своей таблицы. Или просто использовать приватные API, чтобы воспроизвести поведение UITableViewController при инициализации. О «радиусе кривизны» таких решений можно спорить – спасибо Apple за «классный» API.
Нет, дело именно в том, что UIRefreshControl неправильно инициализируется. Немного покопавшись в runtime легко убедиться, что UITableViewController при его инциализации дополнительно привязывает UIRefreshControl к UITableView – у таблицы вызывается приватный метод:
google indirect enum
Действительно, эту задачу правильнее решать через
setCollectionViewLayout
При этом все эти украшательства искусственно ограничивают доступные возможности. Потом эти возможности либо а) не используются б) обрастают дублирующими «своими» API-обёртками.
Вместо просто использования стандартных API, разработчики, приходя на такой проект, вынуждены разбираться в особенностях очередного «фреймворка».
Статья полезная в плане понимания, как git работает на более низком уровне, чем обычный пользовательский UI (CLI). Но с практической частью я совсем не согласен – все описанные задачи можно решать обычными, высокоуровневыми командами, т.е. более понятно и наглядно.
Низкоуровневые операции с tree почти всегда можно заменить на обычные манипуляции с ветками. Человеческая версия:
Не понял, зачем это, если сравнить можно просто
git diff alpha origin/beta
Аналогично п. 1. Но вообще это странное желание смешивать в кучу разные изменения, я бы всегда предпочёл наглядную историю с отдельными ревертами:
– сделает все реверт-коммиты в правильном порядке за один вызов
Всё это делает просто checkout с коммитом и путём:
Аналогично п. 1
На практике я бы такое никогда не использовал:
Ну что сказать, хреновый workflow, который заставляет всегда делать rebase. Когда конфликты в ветке "фантомные", это хороший пример, когда нужно делать merge и избежать всех недостатков. Главный из которых – несобирающиеся промежуточные версии.
Предлагаю это не делать вообще…
Зарегистрированные стандартным образом кастомные протоколы вроде как раз в любых конфигурациях
NSURLSession
работают.protocolClasses
как раз для локального расширения отдельной конфигурации.Но
AVPlayer
вроде и правда кNSURLProtocol
не привязать, хотя бы потому что логика загрузки там нужна более специфичная и сложная, что и видно в API.С чего вы это взяли? Есть какое-нибудь подтверждение?
В iOS7 и iOS8 появилось несклько API, которые как раз подходят для решения подобных задач: View Controller Transitions, UIPresentationController
1. Вы используете -viewDidLoad как место «мгновенного» перехода к следующему контроллеру, хотя это совершенно неподходящее место для выполнения подобных действий – нужно правильно понимать жизненный цикл UIViewController и назначение соотвествующих методов.
2. В вашем случае view первого (Info) контроллера всегда загружается, хотя в большинстве сценариев это бесполезно, т.к. пользователь его никогда не увидит – опять же нужно понимать жизненный цикл контроллера, в частности – когда инициализируется его view.
3. Вы реализуете логику *навигации* внутри отдельно взятого контроллера – это нарушает принятые в системе уровни абстракции. Представьте, что получится, когда вам потребуется показывать Info контроллер где-то в другой части приложения (или например в iPad-версии) – другим способом и в другом контексте навигации.
Есть много вариантов, которые не обладают такими недостатками, а главное – решают задачу на правильном уровне абстракции. В простом варианте можно реализовать соотвествующую логику в AppDelegate:
Впоследствии UITableView использует эту связь с UIRefreshControl – как раз для вычисления правильного contentInset при овер-скроллинге.