Що робить менеджер завантажень такого, чого не робить веббраузер
Чотиригігабайтний файл, дев’яносто відсотків готово — і тут телефонний дзвінок, або просто заблокований екран, і все зникло. Це найпоширеніша скарга на завантаження в iOS, і це не баг. Операційна система робить точно те, для чого її спроєктовано, і саме тому існує окремий клас застосунків.
- 30 с Приблизно стільки призупинений застосунок продовжує працювати, перш ніж iOS його зупинить
- 206 Статус HTTP, який узагалі робить відновлення можливим
- 1 байт Скільки повторно завантажується при правильно відновленому передаванні
Чому передавання зупиняється при перемиканні застосунків
iOS не дозволяє застосунку продовжувати працювати просто тому, що йому так хочеться. Коли ти виходиш із застосунку, він призупиняється за секунди, а призупинений застосунок не має процесорного часу, мережевих сокетів і жодного способу помітити, що його зупинили. Усе, що він тримав у пам’яті, залишається на місці, але замороженим — а якщо системі знадобиться пам’ять, застосунок буде завершено напряму, без попередження.
Тому передавання, що виконується на звичайному з’єднанні всередині застосунку, закінчується в момент жесту переходу на головний екран. Деякі застосунки приховують це, запитуючи кілька додаткових секунд фонового часу, — саме тому завантаження іноді переживає перехід у фон рівно настільки, скільки потрібно, щоб ти помітив, що воно все ж перервалося.
Правильна відповідь — інша за своєю природою. iOS надає сервіс фонового передавання: ти передаєш системі список URL-адрес і призначень, а завантаженням займається сама система, у власному процесі, за власним розкладом. Твій застосунок може бути призупинений, завершений або взагалі не запущений — передавання триває, а застосунок перезапускається у фоні, коли з’являється що повідомити. Це механізм, що стоїть за кожним завантаженням, яке переживає заблокований екран, і використання його — це рішення дизайну, прийняте застосунком заздалегідь, а не налаштування, яке можна ввімкнути.
Чотири механізми, що вирішують, чи переживе завантаження перерву
- Range-запит
- HTTP-запит, що просить байти від 5 000 000 і далі замість усього файлу. Якщо сервер відповідає
206 Partial Content, відновлення з середини можливе; якщо відповідає200 OKі починає із самого початку — ні, файл доведеться завантажувати заново з нуля. - Паралельні з’єднання
- Розбиття одного файлу на кілька діапазонів і завантаження їх одночасно. Це допомагає тому, що одне з’єднання часто обмежується сервером або затримкою в обидва боки, а не тому, що твій інтернет стає швидшим від більшої кількості відкритих сокетів.
- Підтверджене зміщення (committed offset)
- Скільки файлу вже безпечно записано на диск, на відміну від того, що ще в дорозі. Завантаження, що відновлюється з останнього підтвердженого байта, коректне; те, що відновлюється з того, що воно *думає*, що отримало, дає пошкоджений файл, який виявить себе лише через кілька годин.
- Фонова сесія
- Описане вище передавання, яким керує система. Стартує повільніше, не дозволяє довільну кастомну логіку, і це єдине, що продовжує працювати, коли застосунок не працює.
Чому завантаження не вдається і як виглядає кожен збій
Більшість повідомлень про «завислу закачку» — це одна з цих п’яти ситуацій, і їх легко розрізнити, щойно знаєш форму.
| Що ти бачиш | Що насправді відбувається | Що допомагає |
|---|---|---|
| Зупиняється в мить виходу із застосунку | Передавання виконувалося всередині процесу застосунку, а не у фоновій сесії. | Ззовні нічого не вдієш — це питання дизайну застосунку. |
| Щоразу перезапускається з 0% | Сервер ігнорує range-запити, тож немає способу продовжити з середини. | Стабільне з’єднання або менший файл. Деякі хости дозволяють діапазони лише для підписаних посилань. |
| Раз по раз падає через кілька хвилин | Термін дії посилання минув. Багато хостів видають URL, чинні лише п’ять-десять хвилин. | Отримай посилання заново з його сторінки й почни спочатку; старе не запрацює ніколи. |
| Завантажується швидко, але файл не відкривається | Прийшла HTML-сторінка помилки або сторінка входу під іменем відеофайлу. | Перевір розмір — «фільм» на 14 КБ це вебсторінка. Огляньте посилання, перш ніж запускати завантаження. |
| Дуже повільно попри швидке з’єднання | Обмеження швидкості на боці сервера для кожного з’єднання окремо. | Більше паралельних з’єднань, якщо сервер це дозволяє. Якщо ліміт по IP-адресі, а не по сокету — нічого не допоможе. |
Коли файлу для завантаження взагалі не існує
Значна частина відео в мережі доставляється не як файл. Вона доставляється як HLS — плейлист .m3u8, що перелічує сотні маленьких сегментів по кілька секунд, часто на кількох рівнях якості, щоб плеєр міг перемикатися залежно від твого з’єднання. Немає жодного окремого URL, що містив би весь фільм, бо фільм існує лише як послідовність.
Зберегти таке означає завантажити кожен сегмент, а потім ремультиплексувати їх: записати відео- та аудіопотоки у звичайний контейнер MP4. Нічого не перекодовується, тож нічого не втрачається, і це займає секунди, а не тривалість самого фільму. Результат — звичайний файл, який відтворюється будь-де.
Саме тому «завантажити цей потік» помітно довше стартує, ніж завантаження файлу: спочатку потрібно отримати й розібрати плейлист, обрати рівень якості, і лише тоді почнуть надходити сегменти. І саме тому деякі потоки взагалі не можна зберегти: якщо сегменти зашифровані за схемою DRM, ключі свідомо недосяжні, і жоден інструмент, що поважає закон, цього не обійде.
Що відрізняє справжній менеджер завантажень від кнопки «завантажити»
Переживає закриття застосунку
Фонові передавання, передані системі, з передачею естафети, яка продовжує з того самого підтвердженого байта, а не починає файл заново.
Повідомляє, що таке посилання, ще до старту
Розмір, тип і чи підтримує сервер відновлення — усе можна дізнатися одним HEAD-запитом, і все це корисно ще до того, як ти витратиш чотири гігабайти з тарифного плану.
Ставить у чергу, а не заливає всім одразу
Десять файлів одночасно повільніші за три за раз, бо кожному з’єднанню дістається менша частка, а збої множаться. Черга з розумним лімітом одночасності завершується швидше.
Результат — звичайний файл
У папці, яку ти бачиш, із розумною назвою, який відтворить будь-що, — а не блоб бази даних, який відкриє лише той самий застосунок.
Звички, що запобігають більшості проблем із завантаженням
- Починай великі файли на Wi-Fi і тримай екран увімкненим перші кілька секунд
Передача естафети у фонову сесію відбувається на самому початку; після цього екран уже не має значення.
- Не став у чергу двадцять файлів одразу
Три-п’ять одночасних передавань — оптимальна кількість майже для будь-якого з’єднання.
- Перевіряй вільне місце заздалегідь, а не постфактум
Передавання, що заповнює диск, падає на 98%, а iOS до того часу вже могла очистити твій кеш, шукаючи місце.
- Стався з підозрою до миттєвого «завершено»
Фільм, що «завантажився» за дві секунди, — це сторінка помилки. Подивись на розмір файлу.
- Отримуй посилання з простроченим терміном заново з їхньої сторінки
Повторна спроба з мертвим підписаним URL провалюватиметься вічно, скільки б разів застосунок не пробував.
Чим це відрізняється між пристроями
Найсуворіше середовище: призупинення агресивне, а сховище обмежене. Фонові сесії тут не оптимізація, а єдине, що взагалі працює.
Ті самі правила, але з більшим простором для маневру — і єдиний пристрій на iOS, де велика бібліотека може розумно опинитися на зовнішньому накопичувачі замість внутрішнього сховища.
Призупинення взагалі немає, тож довгі передавання поводяться так само, як і на будь-якому десктопі. Практична межа — це сервер, а не операційна система.
Питання, які це піднімає
Чи означає більше з’єднань завжди швидше завантаження?
Ні. Вони допомагають, коли сервер обмежує швидкість кожного окремого з’єднання, а це поширена ситуація. Вони не дають нічого, коли обмежене саме твоє з’єднання, і можуть погіршити ситуацію, коли хост рахує сокети на IP-адресу й починає їх відхиляти. Десь між чотирма і вісьмома — корисний діапазон; тридцять уже шкодить.
Чи може завантаження тривати, поки екран заблоковано?
Так, якщо його передано системному сервісу фонового передавання. Екран блокування не має жодного значення для цього сервісу — важливе саме призупинення застосунку, і весь сенс механізму в тому, щоб продовжувати попри це.
Чому моє завантаження перезапускається замість того, щоб відновитися?
Сервер не виконав range-запит. Це видно з того, що прогрес повертається до нуля, а не продовжується з місця зупинки. Деякі хости підтримують діапазони лише для своїх підписаних URL завантаження, деякі вимикають їх повністю, а декілька підтримують для маленьких файлів, але не для великих.
Чи є перетворення потоку на MP4 тим самим, що й перекодування?
Ні. Ремультиплексування переносить наявні відео та аудіо в контейнер MP4 без змін — без втрат і достатньо швидко, щоб завершитися за секунди. Перекодування перебудовує зображення іншим кодеком і завжди втрачає якість. Якщо збереження двогодинного потоку триває дві години, щось перекодовується там, де в цьому не було потреби.
Як FoxDL завантажує
У рушія два шляхи: внутрішній процес, швидкий, поки застосунок на екрані, і системна фонова сесія, яка переймає естафету з того самого байта, коли його немає.
- Паралельні шматки для одного файлу, що записуються прямо в кінцеву позицію на диску, а не в тимчасові частини, які потім треба об’єднувати.
- Фонові передавання, що продовжуються, коли застосунок покидає екран, і відновлюються з останнього підтвердженого зміщення — а не з того байта, який застосунок думав, що отримав.
- Відновлення після обриву, перезавантаження чи примусового завершення, за умови, що сервер підтримує range-запити. Якщо ні, FoxDL так і скаже, замість того щоб зациклюватися.
- Потоки HLS ремультиплексуються в MP4, тож у бібліотеці опиняється звичайний файл, а не папка із сегментами.
- Інспектор завантаження, який повідомляє реальний розмір, тип і підтримку відновлення посилання ще до старту.
- Усе потрапляє у звичайну папку, яку бачить застосунок «Файли».
Безкоштовні ліміти відрізняються за платформами: на iPhone і iPad — невелика кількість спроб, що поповнюється коротким рекламним роликом за винагороду, який ти запускаєш сам; на Mac, де реклами взагалі немає, — фіксована денна кількість. Pro знімає обмеження на кожному пристрої.
Часті запитання
- Чи тривають завантаження, коли я виходжу із застосунку?
- Чи може перерване завантаження відновитися з того місця, де зупинилося?
- Чи може FoxDL завантажити потік HLS (m3u8)?
- Чому моє завантаження повільне, і чи можна його пришвидшити?
- Скільки завантажень я можу зробити в безкоштовній версії?
Читати далі
Що має статись, перш ніж вебсторінка віддасть тобі свій файл
Чотири способи, якими сторінка доставляє відео, і чому лише один із них — файл, який можна зберегти.
Де насправді живуть твої файли на iPhone і хто може їх бачити
Пісочниця, куди насправді потрапляють завантаження і чому перейменування файлу ламає стільки застосунків.
Чому твій iPhone відкриває один відеофайл і відмовляється відкривати наступний
Контейнери, кодеки і три способи подивитись файл, який iOS відмовляється відкривати.
Твоя бібліотека нарешті в одному місці.
Безкоштовне завантаження. Без облікового запису — повний набір у безкоштовній версії.