Почему передаётся только 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 при овер-скроллинге.