fa
Feedback
Мобильная разработка #1

Мобильная разработка #1

رفتن به کانال در Telegram

Всё о создании приложений под Android и iOS в одном месте. 🔹 Инструменты, библиотеки и ресурсы для ускорения работы. 🔹 Статьи и гайды для разработчиков любого уровня. 🔹 Тренды мобильной разработки и новости индустрии. Реклама @evgenycarter

نمایش بیشتر
3 850
مشترکین
-124 ساعت
-47 روز
-830 روز
آرشیو پست ها
🤖 Хватит быть «человеком-компилятором» на Code Review Вам знакомо это чувство, когда вы открываете Pull Request коллеги, и в
🤖 Хватит быть «человеком-компилятором» на Code Review Вам знакомо это чувство, когда вы открываете Pull Request коллеги, и вместо того, чтобы проверять логику, пишете: 🔵«Тут лишний пробел» 🔵«Название функции с большой буквы?» 🔵«Удали неиспользуемый импорт» Это трата дорогого времени разработчика. Эти споры (Tab vs Space, где ставить фигурную скобку) должны решать роботы, а не люди. В 2026 году стыдно не иметь настроенный Linter (Линтер) в проекте. 🛠 Что подключить прямо сейчас: 🤖 Android (Kotlin): 1. Ktlint: Следит за стилем кода (официальный Kotlin Style Guide). Умеет сам форматировать файл по команде (./gradlew ktlintFormat). Больше никаких споров о пробелах. 2. Detekt: Это уже тяжелая артиллерия. Он ищет не просто кривые отступы, а потенциальные баги: слишком сложные функции, магические числа, пустые блоки catch. 🍏 iOS (Swift): 1. SwiftLint: Стандарт индустрии. Настраивается через .swiftlint.yml. Может кидать Warning (желтое) или Error (красное), если код не соответствует правилам команды. 🔵Пример правила: force_cast (запрет на использование as!), line_length (длина строки). 🚀 Уровень Pro (Git Hooks): Настройте Pre-commit hook. Это скрипт, который запускает линтер до того, как коммит вообще создастся. Если линтер найдет ошибку - Git просто не даст сделать коммит. Итог: В репозиторий физически невозможно запушить «грязный» код. 💡Договоритесь с командой о правилах один раз, запишите их в конфиг линтера и забудьте. Code Review должен быть про архитектуру и надежность, а не про красоту текста. У вас в проекте стоит жесткий запрет на варнинги (Treat warnings as errors) или «пусть висят»? 👇 #ci #quality #detekt #swiftlint #ktlint #automation #middle 👉 @developer_mobila

🏎 Гонка потоков: Баг, который исчезает, когда вы пытаетесь его найти Представьте ситуацию: у вас на банковском счете 100$. В
🏎 Гонка потоков: Баг, который исчезает, когда вы пытаетесь его найти Представьте ситуацию: у вас на банковском счете 100$. Вы и ваша жена одновременно (в одну миллисекунду) пытаетесь снять 10$ через разные банкоматы. В теории должно остаться 80$. На практике, из-за Race Condition, может остаться 90$. Банк потерял деньги. 💸 Почему так происходит? Даже простая операция count++ (увеличение счетчика) для процессора - это три действия: 1. Считать текущее значение (100). 2. Прибавить единицу (101). 3. Записать новое значение (101). Если два потока начнут выполнять шаг 1 одновременно, они оба "увидят" 100. Оба прибавят 1 и запишут 101. Одно действие потеряется навсегда. 🐛 Heisenbug (Гейзенбаг): Самое страшное в гонках то, что они часто исчезают, когда вы начинаете дебажить (добавляете print или брейкпоинты), так как это меняет тайминги выполнения потоков. 🛡 Как защититься (Инструменты Мидла): 🤖 Android (Kotlin): 🔵Atomic-типы: Для простых счетчиков используйте AtomicInteger или AtomicBoolean. Они гарантируют атомарность операций. 🔵Mutex (для Coroutines): Это "светофор" для корутин.

val mutex = Mutex()
mutex.withLock {
    // Код здесь выполняется только одним потоком за раз
    count++
}

StateFlow: Позволяет безопасно обновлять состояние UI, избегая гонок. 🍏 iOS (Swift):Actors (Swift 5.5+): В 2026 году это стандарт. Акторы автоматически защищают свое изменяемое состояние. Вам не нужны ручные блокировки.

actor BankAccount {
    var balance = 100
    func withdraw(amount: Int) { balance -= amount }
}

Serial Queues (GCD): Старая добрая очередь, где задачи выполняются строго по одной. 💡 Совет: Если у вас в приложении есть переменная var, которую меняют из разных фоновых потоков, это бомба замедленного действия. Заверните её в Atomic, Mutex или Actor. Сталкивались с багами, которые невозможно повторить на устройстве разработчика? 👇 #concurrency #multithreading #android #ios #kotlin #swift #bugs 👉 @developer_mobila

💉 Dependency Injection: Зачем усложнять, если можно просто написать new? Когда новичок видит код с кучей аннотаций @Inject и
💉 Dependency Injection: Зачем усложнять, если можно просто написать new? Когда новичок видит код с кучей аннотаций @Inject или модулей, у него возникает вопрос: "Зачем всё это? Я же могу просто создать объект внутри класса!"Код Джуна (Hard dependency):

class UserRepository {
    // Мы "приварили" конкретную базу данных к репозиторию
    private val database = SQLiteDatabase() 

    fun getUser() { ... }
}

В чем проблема? Представьте, что вы строите дом. Этот код как если бы вы вмуровали кофемашину прямо в стену кухни. 1. Хотите заменить кофемашину на новую? Придется ломать стену (переписывать код класса). 2. Хотите протестировать кухню, не варя кофе? Не получится, машина там намертво. ✅ Код Мидла (Dependency Injection):

class UserRepository(private val database: Database) { 
    // Мы просим дать нам ЛЮБУЮ базу данных через конструктор
}

В чем суть? Вы говорите: "Мне для работы нужна база данных. Дайте мне её, я не хочу сам её создавать". Это как розетка. Вы не вмуровываете технику в стену, вы просто втыкаете вилку. Сегодня это дешевый чайник (тестовая база), завтра мощная кофемашина (реальный сервер). 🛠 Инструменты (Что учить): 🤖 Android:Hilt (Dagger): Стандарт от Google. Мощный, проверяет ошибки при компиляции, но сложный в настройке. • Koin: Service Locator (технически не совсем DI, но решает те же задачи). Простой, пишется на чистом Kotlin, но ошибки могут вылезти в рантайме. Идеально для старта. 🍏 iOS:Swinject: Классика DI контейнеров. • Swift Native: В современных проектах часто используют просто Factory Pattern или передачу зависимостей через init, без сторонних библиотек. Это самый чистый путь. 💡 Совет: На собеседовании на вопрос "Что такое DI?" не начинайте рассказывать про даггер. Скажите просто: "Это принцип, когда объекты не создают свои зависимости сами, а получают их извне. Это нужно для тестируемости и гибкости кода". Это ответ уровня Senior. А что используете вы в своих проектах? 👇 #architecture #di #hilt #koin #ios #android #middle #patterns 👉 @developer_mobila

Холодный старт (Cold Start) и как не заставлять пользователя ждать. 🕓 Правило 3 секунд: Почему ваше приложение удаляют сразу
Холодный старт (Cold Start) и как не заставлять пользователя ждать. 🕓 Правило 3 секунд: Почему ваше приложение удаляют сразу после установки Знаете ли вы, что 53% пользователей закрывают и удаляют приложение, если оно грузится дольше 3 секунд? Новички часто совершают одну и ту же ошибку: «Напихаю-ка я инициализацию всей аналитики, рекламы, базы данных и сетевых клиентов в самый старт, чтобы потом всё было готово». В итоге пользователь видит белый экран или зависшее лого на 5 секунд. Это Холодный старт (Cold Start) - момент, когда система создает процесс вашего приложения с нуля. 🛑 Главные убийцы скорости: 1. Тяжелый Application.onCreate (Android) / didFinishLaunching (iOS). Если вы инициализируете 15 библиотек в главном потоке (Main Thread) до того, как покажется первый экран - вы тормозите запуск. 2. Фейковые Сплэш-экраны. Никогда (слышите, никогда!) не делайте Thread.sleep(2000) или таймер на стартовом экране, «чтобы пользователь успел разглядеть логотип». Это бесит. 🚀 Как ускорить запуск (Чек-лист Мидла):Ленивая загрузка (Lazy Init): Инициализируйте тяжелые библиотеки (например, чаты поддержки или карты) только тогда, когда пользователь реально открывает нужный экран, а не при старте. ✅ Фоновые потоки: Если библиотеку нужно загрузить сразу, делайте это в Coroutines (Dispatchers.IO) или DispatchQueue.global(). Главный поток должен заниматься только отрисовкой UI. ✅ Правильный Splash Screen: 🔵🤖 Android: Используйте официальный androidx.core:core-splashscreen. Он нативен, красив и работает мгновенно, пока грузится ваш процесс. 🔵🍎 iOS: Сделайте LaunchScreen.storyboard максимально легким. Никакого кода, только статика. 🛠 Как измерить: Не считайте «на глаз»! 🔵Android: В логах (Logcat) ищите строку Displayed. Там система сама пишет: ActivityManager: Displayed com.app/.StartActivity: +850ms. 🔵iOS: В Xcode зайдите в Product -> Profile -> App Launch. Instruments покажут каждый миллисекунду задержки. А вы следите за временем запуска или надеетесь на мощные смартфоны пользователей? 👇 #performance #optimization #android #ios #coldstart #middle 👉 @developer_mobila

🔐 Вы только что подарили хакерам доступ. Где НЕЛЬЗЯ хранить ключи Классическая история: вы пишете пет-проект, используете AP
🔐 Вы только что подарили хакерам доступ. Где НЕЛЬЗЯ хранить ключи Классическая история: вы пишете пет-проект, используете API (например, ChatGPT или Firebase), и пишете прямо в коде: val apiKey = "sk-proj-12345..." Потом git push, и вы идете спать. А утром ваш ключ заблокирован, или с карты списали деньги за чужой трафик. 🤖 Реальность: Боты сканируют публичные репозитории GitHub на наличие строк, похожих на ключи, за секунды после публикации. Удалить коммит не поможет, он уже в кеше у злоумышленников. Как делать правильно (Middle Way): Секреты никогда не должны попадать в систему контроля версий (Git). Они должны жить только локально на вашем компьютере. 🤖 Android: Используйте файл local.properties. Он по умолчанию добавлен в .gitignore. 1. Откройте local.properties и добавьте: MY_API_KEY="ваш_ключ". 2. В build.gradle (app) считайте его и прокиньте в код:

defaultConfig {
    buildConfigField("String", "API_KEY", gradleLocalProperties(rootDir).getProperty("MY_API_KEY"))
}

3. В коде используйте: BuildConfig.API_KEY. 🍏 iOS: Вариантов много, но самый простой для старта: 1. Создайте файл Secrets.xcconfig (или .plist). 2. Сразу же добавьте его в .gitignore. 3. Запишите ключ туда. 4. В настройках проекта (Build Settings) подключите этот конфиг или считывайте файл программно. 🛡 Золотое правило: Если вы клонируете свой проект на чистый ноутбук, он не должен собраться сразу. Он должен попросить вас создать локальный файл с ключами. Это не баг, это безопасность. Признавайтесь, случалось случайно комитить пароли или токены? 👇 #security #android #ios #git #tips #middle #safety 👉 @developer_mobila

🧹 Убираем за собой: Как не опозориться при Code Review Знакомая ситуация? Вы работали над фичей, сделали 10 коммитов с назва
🧹 Убираем за собой: Как не опозориться при Code Review Знакомая ситуация? Вы работали над фичей, сделали 10 коммитов с названиями: 🔵init 🔵wip 🔵fix crash 🔵fix typo 🔵aaaaa rabotay pls А потом отправляете это в Pull Request. Тимлид открывает историю и… плачет кровавыми слезами. 🩸 Отличное правило хорошего тона: «Ветка может быть грязной, пока она локальна. Но в main должен уйти чистый и атомарный код». Вам нужен Git Interactive Rebase. Это магия, которая позволяет переписать историю. 🛠 Как это сделать (Консоль / IDE): Допустим, вы хотите объединить последние 5 мелких коммитов в один красивый. 1. Пишем в терминале: git rebase -i HEAD~5 2. Откроется редактор со списком ваших коммитов. Перед каждым стоит слово pick. 3. Меняем команды: 🔵Оставляем pick у самого первого (верхнего) коммита. 🔵У остальных меняем pick на squash (или s) - это значит «сплющить» этот коммит с предыдущим. 🔵Если хотите переименовать - используйте reword. 4. Сохраняем и закрываем. Git предложит написать одно общее сообщение для нового «супер-коммита». 5. Отправляем на сервер: git push --force (Осторожно! Делайте это только в своей ветке, пока никто другой в ней не работает). 💡 Результат: Вместо 5 мусорных записей у вас одна красивая: Feature: Added dark mode implementation. Коллеги на ревью скажут спасибо: ✅ Проще читать изменения. ✅ Если баг - проще откатить один коммит, чем искать в куче мелких. А вы используете Rebase или предпочитаете честную историю со всеми «фиксами»? 👇 #git #teamwork #middle #tips #tools #bestpractices 👉 @developer_mobila

🍝 Ваш код похож на спагетти? Синдром «Божественного объекта» Знакомая картина: открываешь проект, заходишь в MainActivity ил
🍝 Ваш код похож на спагетти? Синдром «Божественного объекта» Знакомая картина: открываешь проект, заходишь в MainActivity или ProfileViewController, а там... 1500 строк кода. 😱 Там и работа с сетью, и валидация полей, и анимации, и сохранение в базу, и даже форматирование даты. В мире разработки это называется God Object (или Massive View Controller). Почему это плохо? 1. Невозможно тестировать. Как написать юнит-тест на класс, который делает всё? 2. Сложно менять. Поправил верстку — сломалась база данных. 3. Конфликты при слиянии. В команде двое разработчиков полезли в этот файл — здравствуй, merge conflict на полдня. 🚀 Как лечить (Гайд для перехода в Middle): Если видишь класс больше 300-400 строк, начинай «резню»: 1. ✂️ Всю логику сети - в Repository. Во View/Activity не должно быть http-клиентов и JSON-парсинга. Она должна просто сказать: repository.getUsers() и показать спиннер. 2. ✂️ Всю бизнес-логику - в UseCases (Интеракторы). Валидация пароля, подсчет корзины, фильтрация списков - это чистая логика. Выносите её в отдельные классы (PasswordValidator, CartCalculator). 3. ✂️ Сложный UI - в Custom Views / Child ViewControllers. Если у вас в адаптере списка 500 строк кода настройки ячеек - вынесите ячейку в отдельный класс с методом bind(data). 💡 Правило одной ответственности (SRP): Класс должен иметь только одну причину для изменения. 🔵Если дизайнер поменял цвет кнопок - меняем только View. 🔵Если бэкенд поменял формат JSON, меняем только DTO/Repository. 🔵Если эти изменения заставляют вас править один и тот же файл, у вас архитектурная проблема. 🏁 Задание на неделю: Найдите самый «жирный» класс в своем проекте и попытайтесь вынести из него хотя бы одну функцию в отдельный вспомогательный класс. Ваш код скажет вам спасибо. Сколько строк в самом большом файле вашего текущего проекта? Пишите честно 👇 #architecture #cleanCode #refactoring #middle #android #ios 👉 @developer_mobila

👆 Почему пользователи ненавидят ваши кнопки (даже если они красивые) Знакомая ситуация: вы сверстали экран идеально по макет
👆 Почему пользователи ненавидят ваши кнопки (даже если они красивые) Знакомая ситуация: вы сверстали экран идеально по макету. Иконка «Закрыть» (крестик) - ровно 24x24, как нарисовал дизайнер. Но пользователи бесятся, тыкая в нее по 5 раз, и не могут попасть. Это классическая ошибка новичка: путать видимый размер и кликабельную область. В гайдлайнах (HIG и Material Design) написано кровью: 🔴 Минимальная область нажатия: 🔵🍎 iOS: 44x44 pt 🔵🤖 Android: 48x48 dp Если ваша иконка меньше (например, 24x24), вы обязаны искусственно увеличить область нажатия, не меняя визуал. Как это сделать грамотно: 🤖 Android (Compose & XML): 🔵Compose: Используйте модификатор .minimumInteractiveComponentSize(). Он сам добавит невидимые отступы, чтобы дотянуть размер до 48dp. 🔵XML: Добавьте padding="12dp" к самому ImageView или оберните его в прозрачный контейнер, на который повесьте клик. Не используйте TouchDelegate без крайней нужды, это больно. 🍏 iOS (SwiftUI & UIKit): 🔵SwiftUI: Распространенная ошибка — вешать .onTapGesture на маленькую иконку. 🔵Плохо: Image("close").onTapGesture { ... } 🔵Хорошо: Image("close").frame(width: 44, height: 44).contentShape(Rectangle()).onTapGesture { ... } (мы делаем прозрачную рамку вокруг). 🔵UIKit: Переопределите метод point(inside:with:) в кнопке, чтобы она ловила касания за своими пределами. 💡 Лайфхак: Включите в настройках разработчика на телефоне «Показывать границы элементов» (Show layout bounds). Если вы видите маленькие прямоугольники вокруг кнопок, это повод для рефакторинга. Заботьтесь о пальцах своих пользователей! А вы спорите с дизайнерами, когда они рисуют слишком мелкие элементы? 👇 #ux #ui #android #ios #tips #mobile #design 👉 @developer_mobila

🛑 Хватит спамить принтами! Дебажим как профи Признавайтесь, делали так? У вас есть цикл на 100 элементов, и ошибка вылетает
🛑 Хватит спамить принтами! Дебажим как профи Признавайтесь, делали так? У вас есть цикл на 100 элементов, и ошибка вылетает только на 87-м. Вы ставите обычный брейкпоинт и 86 раз яростно жмете «Resume Program» (▶️), проклиная всё на свете, пока не дойдете до нужного состояния. Или еще хуже: Log.d("TAG", "Я тут") Log.d("TAG", "А теперь тут, значение i = $i") Есть способ элегантнее, который отличает опытного разработчика от новичка - Conditional Breakpoints (Условные точки останова). Они останавливают выполнение программы только тогда, когда выполняется определенное условие. Как это сделать за 5 секунд: 🤖 Android Studio (IntelliJ IDEA): 1. Поставьте обычный красный брейкпоинт. 2. Нажмите на него правой кнопкой мыши. 3. В поле "Condition" напишите условие на языке Kotlin/Java. Пример: item.id == 87 или user.name.contains("Test") && i > 50 4. Готово! Студия проигнорирует первые 86 итераций и остановится точно там, где нужно. 🍎 Xcode: 1. Поставьте синий брейкпоинт. 2. Нажмите на него правой кнопкой (или двойной клик) -> "Edit Breakpoint". 3. В поле "Condition" пишите условие на Swift. Пример: indexPath.row == 87 💡 Бонус-фича для тех, кто не любит останавливаться: В настройках брейкпоинта уберите галочку Suspend (Остановить) и поставьте галочку Log Message (Evaluate and log). Теперь IDE будет сама писать в консоль значения переменных при прохождении этой точки, не останавливая приложение. Это те же принты, только вам не нужно пачкать ими код и пересобирать проект! Какая ваша любимая фишка дебаггера, о которой мало кто знает? Делитесь в комментариях 👇 #productivity #androidstudio #xcode #debug #tips #middle 👉 @developer_mobila

☠️ Баг, который вы не видите, а пользователи ненавидят Представьте: пользователь заполнил длинную форму регистрации, свернул
☠️ Баг, который вы не видите, а пользователи ненавидят Представьте: пользователь заполнил длинную форму регистрации, свернул приложение, чтобы скопировать код из SMS, возвращается... а экран пустой. Данные исчезли. 🤬 Это System-initiated process death. Самая частая причина удаления приложения у пользователей и головная боль разработчиков. Почему это происходит? ОС (Android или iOS) всегда не хватает оперативной памяти. Когда ваше приложение уходит в фон, система может «тихо» убить его процесс, чтобы освободить ресурсы для активного окна (например, Камеры). ❌ Ошибка новичка: «Я храню данные в ViewModel (Android) или в переменной контроллера (iOS), они же живут долго!» Реальность: ViewModel переживает поворот экрана, но умирает вместе с процессом. Синглтоны тоже сбрасываются. ✅ Как делать правильно (Level Up): 🤖 Android: Перестаньте полагаться только на поля класса. Используйте SavedStateHandle. Это специальный механизм внутри ViewModel, который сохраняет небольшие кусочки данных (ID, поисковый запрос, ввод пользователя) в системный бандл. Система бережно восстановит его даже после смерти процесса. Гуглить: SavedStateHandle, Parcelable. 🍏 iOS (SwiftUI/UIKit): В SwiftUI для простых данных (например, выбранная вкладка или текст) используйте обертку @SceneStorage. Она автоматически сохраняет и восстанавливает состояние. Для сложных данных — сохраняйте их в локальную БД (CoreData/Realm/SwiftData) при каждом изменении, а не при закрытии экрана. 🛠 Как проверить себя (Челлендж на 5 минут): Не верьте эмулятору. Проверьте свой текущий проект прямо сейчас: 1. Запустите приложение и введите данные в любое поле. 2. Сверните приложение (Home). 3. Android: В настройках разработчика включите опцию «Don't keep activities» (Не сохранять действия). 4. iOS: В Xcode нажмите Debug -> Simulate Memory Warning или остановите дебаг и запустите другое тяжелое приложение. 5. Вернитесь в свое приложение. Если данные исчезли или случился краш, поздравляю, вы нашли критический баг. Время фиксить! Знали про SavedStateHandle или по старинке сохраняли всё в базу данных? 👇 #android #ios #bugs #middle #architecture #обучение 👉 @developer_mobila

🛠 Хватит писать To-Do листы! Топ бесплатных API для твоего портфолио Рекрутеры видят сотни «списков задач» и «калькуляторов»
🛠 Хватит писать To-Do листы! Топ бесплатных API для твоего портфолио Рекрутеры видят сотни «списков задач» и «калькуляторов». Чтобы выделиться, нужно показать работу с сетью, сложным UI, кэшированием и картинками. Лучший способ это сделать - написать клиент для реального API. Вот подборка бесплатных, стабильных и открытых API, на которых можно построить крутой проект: 🎬 1. The Movie DB (TMDB) 🔵 Что там: Огромная база фильмов, актеров, рейтингов и постеров. 🔵 Чему научишься: Работать со сложными списками (RecyclerView/LazyColumn), пагинацией, поиском и загрузкой изображений (Glide/Coil/Kingfisher). 🔵 Идея: Клон Netflix или «Кинопоиска». 🚀 2. NASA Open APIs 🔵 Что там: Фото дня (APOD), данные о Марсе, астероидах. 🔵 Чему научишься: Работать с красивым медиа-контентом и датами. 🔵 Идея: Приложение «Космос сегодня» с ежедневными уведомлениями. 3. PokéAPI 🔵 Что там: Всё о покемонах. Полностью открытое, не требует ключа (Auth Key). 🔵 Чему научишься: Архитектуре. Данные хорошо структурированы, идеально для тренировки Clean Architecture и маппинга JSON в модели. 🔵 Идея: «Покедекс» с детальной информацией и статами. 📈 4. CoinGecko API 🔵 Что там: Курсы криптовалют в реальном времени. 🔵 Чему научишься: Работать с Websockets (если найдешь) или частым обновлением данных, рисовать графики. 🔵 Идея: Трекер портфеля крипты. 💡 Совет ментора: Не пытайтесь сделать всё сразу. Возьмите один экран (например, список популярных фильмов) и сделайте его идеально: с обработкой ошибок («нет интернета»), скелетоном при загрузке и красивой анимацией. Это ценнее, чем кривое, но большое приложение. Сохраняй подборку, чтобы не потерять! А какое API вы использовали в своем последнем проекте? 👇 #ресурсы #api #петпроект #ideas #android #ios 👉 @developer_mobila

💼 Вопрос с собеседования: «Как вы боретесь с утечками памяти?» Этот вопрос гарантированно зададут на собеседовании и Android
💼 Вопрос с собеседования: «Как вы боретесь с утечками памяти?» Этот вопрос гарантированно зададут на собеседовании и Android, и iOS разработчику. Лид хочет услышать не сухую теорию, а ваши инструменты. Вот как отличается уровень ответов: ❌ Ответ Джуна: «Утечка - это когда память не освобождается, забивается, и приложение падает с ошибкой Out Of Memory. Я стараюсь писать чистый код и надеюсь на Garbage Collector (или ARC в iOS)». 👉 Вердикт: Слишком абстрактно. Не понятно, умеет ли кандидат реально находить и чинить проблемы в коде. ✅ Ответ Мидла: «Утечки чаще всего возникают, когда объекты удерживаются дольше, чем нужно. Классика жанра: 🤖 Android: Ссылка на Activity или Context внутри статического поля или долгоживущего фонового потока. 🍎 iOS: Retain Cycle (циклические ссылки), когда два объекта сильно ссылаются друг на друга (часто бывает в кложурах). Как я их ищу: 1. Инструменты: Не гадаю на кофейной гуще, а запускаю Android Profiler (или библиотеку LeakCanary) / Xcode Instruments (Leaks & Memory Graph). 2. Лечение: Использую WeakReference или [weak self], чтобы разорвать сильную связь». 👉 Вердикт: Четкое понимание причины + знание профайлеров + конкретное решение. 💡 Совет: Перед следующим собеседованием запустите свой пет-проект с профайлером. Даже если там нет утечек, вы сможете сказать: «Я проверял свой проект через Instruments/Profiler, потребление памяти стабильное». Это огромный плюс в карму. Сталкивались с OOM (Out Of Memory) в реальных проектах или пока проносило? 👇 #собеседование #карьера #ios #android #tips 👉 @developer_mobila

🚀 Что учить мобильному разработчику в 2026 году? Индустрия не стоит на месте. То, что было «модно» пару лет назад, сегодня -
🚀 Что учить мобильному разработчику в 2026 году? Индустрия не стоит на месте. То, что было «модно» пару лет назад, сегодня - стандарт индустрии, а знание легаси-технологий потихоньку отходит на второй план (но все еще нужно для поддержки). Мы собрали ключевые фокусы для Junior и Middle разработчиков на этот год. Сверяйте свои планы! 👇 🤖 Android (Kotlin) 🔵Jetpack Compose: Это уже база. XML верстка уходит в легаси. Если вы еще не перешли на Compose - 2026 год самое время. 🔵KMP (Kotlin Multiplatform): Главный тренд. Бизнес хочет экономить, и шарить логику между iOS и Android стало стандартом. Учитесь выносить Data и Domain слои в общий модуль. 🔵Gradle Version Catalogs: Стандарт управления зависимостями. buildSrc и простое перечисление в build.gradle уступают место TOML-файлам. 🍎 iOS (Swift) 🔵SwiftUI: Как и с Android - это база для новых проектов. UIKit знать нужно (его еще много), но пилить новые экраны лучше декларативно. 🔵Swift 6 & Concurrency: Разберитесь наконец с async/await и Actors. Понимание потокобезопасности отличает Мидла от Джуна. 🔵Смотрим в сторону KMP: Да, iOS-разработчикам тоже полезно понимать, как подключать общие модули на Kotlin. Это повышает вашу ценность на рынке. 🛠 Общее (Must Have) 🔵AI-ассистенты: Copilot, Cursor или встроенные AI в IDE. Это не «чит», это инструмент ускорения. Учитесь писать правильные промпты для рефакторинга и тестов. 🔵CI/CD: Понимание, как ваше приложение собирается и летит в стор (GitHub Actions, Fastlane). Не ждите, пока это сделает DevOps, разберитесь сами. 🎓 Совет новичкам: Не пытайтесь выучить всё сразу. Выберите одну киллер-фичу (например, Compose или Concurrency) и углубитесь в нее в этом месяце. 💬 Вопрос: Какую технологию вы поставили себе в план изучить первой в этом году? Пишите в комментарии, обсудим! 👇 #roadmap #карьера #android #ios #тренды2026 👉 @developer_mobila

👨‍💻 Как писать чистый код на SwiftUI: вспоминаем паттерны Легко написать работающий экран на SwiftUI. Сложно написать подде
👨‍💻 Как писать чистый код на SwiftUI: вспоминаем паттерны Легко написать работающий экран на SwiftUI. Сложно написать поддерживаемое приложение. Часто проблема кроется в непонимании того, какие паттерны уже "зашиты" в фреймворк. В этой статье автор разбирает 5 основных паттернов, которые вы, скорее всего, уже используете, но не называете их своими именами: 🔹 Observer - основа реактивности SwiftUI. 🔹 Builder - магия, которая позволяет писать декларативный UI. 🔹 Adapter - мост в мир UIKit. 🔹 Decorator - суть всех модификаторов. 🔹 Strategy - способ гибкой настройки логики. Понимание этих концепций поможет не изобретать велосипед, а писать идиоматичный код. https://medium.com/ios-nest/design-patterns-in-swiftui-9091a4fa722e #iOS #Engineering #SwiftUI 👉 @developer_mobila

Repost from Mobile VK Hub
Конец года, и снова заканчиваются все подписки 😱 Узнали? Согласны? Не беда — мы как раз разыгрываем промокоды на год от Облака Mail и VK Музыки! Условия участия простые: 🔹 подпишитесь на наш канал @mobilehubvk 🔹нажмите кнопку «Участвовать» 🔹 дождитесь 30 декабря — в этом посте мы выберем случайным образом 6 победителей Информацию об организаторе, правилах и призах ищите по ссылке. Удачи!

Offline-First - это не просто кэширование GET-запросов Многие путают Offline-Capable (показали кэш, если нет сети) и Offline-First (приложение полностью функционально без сети, сеть - лишь способ синхронизации). На собеседованиях часто слышу: "Ну, сохраним в Room/Realm, а когда появится сеть - отправим на бэкенд". Звучит просто, пока не натыкаешься на Concurrancy & Conflict Resolution. Допустим, у нас таск-трекер. Юзер А (в метро) меняет статус задачи на "Done". Юзер Б (в лифте) меняет описание этой же задачи. Оба выходят в онлайн. Что попадет в базу? Если вы используете стратегию Last Write Wins (LWW), кто-то потеряет данные. О чем стоит думать при проектировании синхронизации: 1. Optimistic UI: Мы обязаны показать изменение мгновенно. Но как откатить стейт, если сервер вернул 409 Conflict или бизнес-валидацию? Нужен надежный механизм транзакций на клиенте. 2. Queue Management: Очередь запросов должна быть персистентной. Но что, если первый запрос упал? Блокировать всю очередь? Или пропустить и нарушить причинно-следственную связь (causality)? 3. CRDTs (Conflict-free Replicated Data Types): Это "Святой Грааль" распределенных систем. - Вместо хранения значения, мы храним операции. - Математика CRDT гарантирует, что независимо от порядка применения операций, итоговое состояние у всех клиентов будет одинаковым (Eventual Consistency). Практические выводы: - Не пишите свои велосипеды для синка, если проект сложнее "To-Do листа". Это распределенная система в миниатюре. - Смотрите в сторону решений, поддерживающих CRDT или дифференциальную синхронизацию "из коробки" (например, PowerSync, Replicache, или старый добрый Couchbase, если позволяет легаси). - Если пишете сами - всегда версионируйте сущности (Vector Clocks) и проектируйте API так, чтобы сервер мог принимать патчи, а не целиковые объекты. Offline-First - это не про базу данных на клиенте. Это про умение разруливать энтропию, когда Source of Truth временно недоступен. #mobile #architecture #systemdesign #offlinefirst 👉 @developer_mobila

SourceCraft: релиз, который поможет ускорить разработку Свежий релиз SourceCraft объединил всё, что нужно команде разработчик
SourceCraft: релиз, который поможет ускорить разработку Свежий релиз SourceCraft объединил всё, что нужно команде разработчиков. 🤖 ИИ стал сильнее — улучшенный поиск уязвимостей и встроенная генерация описаний к изменениям. 🔧 Работа в команде стала проще: поддержка Gitlab CI/CD YAML, обновлённая система релизов и web-интерфейс для решения конфликтов в PR. 🔒 Безопасность — на уровне: дэшборд уязвимостей, страница Code Scanning (SAST), rescan и список библиотек с уязвимостями в SCA. Платформа прошла оценку соответствия ФЗ-152, PCI DSS и ГОСТ 57580. А ещё обновился UI CI/CD и появилась интеграция с Telegram для уведомлений и статусов. Расскажем в подробностях и ответим на вопросы в канале

Heat — это нативный клиент с открытым исходным кодом для iOS и macOS, позволяющий взаимодействовать с самыми популярными LLM-
Heat — это нативный клиент с открытым исходным кодом для iOS и macOS, позволяющий взаимодействовать с самыми популярными LLM-сервисами. Фичи: Поддержка популярных LLM-провайдеров (OpenAI, Mistral, Anthropic, Gemini) Поддержка локальных LLM с открытым исходным кодом с помощью Ollama Поддержка генерирования изображений (Stable Diffusion и Dall-e) Поиск и просмотр веб-страниц для повышения точности ответов Чтение и понимание календаря Поиск в файловой системе (только для десктопа) Базовое сохранение данных в памяти Никаких зависимостей от сервера, кроме доступа к моделям https://github.com/nathanborror/Heat #ios 👉 @developer_mobila

Ускоряем Android-приложения с помощью Baseline Profiles Привет, меня зовут Даниль Гатиатуллин, я инженер юнита Performance в
Ускоряем Android-приложения с помощью Baseline Profiles Привет, меня зовут Даниль Гатиатуллин, я инженер юнита Performance в Авито. Наша команда отвечает за производительность приложения Авито: мы следим за скоростью старта приложения и отрисовки экранов, качеством скролла, отслеживаем сетевые ошибки и занимаемся оптимизациями. В этой статье я расскажу, что такое Baseline Profiles, как он ускоряет запуск программы и каким приложениям он принесет больше пользы. В качестве примера возьму наш эксперимент, который ускорил время запуска приложения на 15%. Также расскажу, как мы автоматизировали добавление профилей в каждый релиз. https://habr.com/ru/companies/avito/articles/842218/ #Android 👉 @developer_mobila

Custom Keyboards SwiftUI - iOS 16+ В этом видео я собираюсь показать, как создавать пользовательские клавиатуры для текстовых полей с использованием SwiftUI источник #ios 👉 @developer_mobila