Библиотека мобильного разработчика | Android, iOS, Swift, Retrofit, Moshi, Chuck
9.84K subscribers
1.45K photos
68 videos
52 files
4.2K links
Все самое полезное для мобильного разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a4adec1b17b35b6c0d8389
Download Telegram
🔗 Реализуем deep links в мобильных приложениях

Пользователи ожидают:

• Плавных переходов из писем/сообщений в приложение
• Сохранения контекста при открытии ссылок
• Рабочих ссылок даже когда приложение не установлено

Базовые концепции:

Deep Links - открывают конкретный экран в приложении
Deferred Deep Links - работают даже без установленного приложения
App Links (Android) / Universal Links (iOS) - веб-ссылки, открывающие приложение

Реализация на Android

1. Добавьте intent-filter в манифест:

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="yourdomain.com"/>
</intent-filter>


2. Обработка ссылки в Activity:

override fun onCreate(savedInstanceState: Bundle?) {
if (intent?.action == Intent.ACTION_VIEW) {
val data = intent.data
// Анализ URL и навигация
}
}


Реализация на iOS

1. Настройка Associated Domains:

<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yourdomain.com</string>
</array>


2. Обработка в AppDelegate:

func application(_ application: UIApplication, 
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else {
return false
}
// Обработка URL
return true
}


Продвинутые сценарии

1. Аналитика переходов:

• Добавьте UTM-метки к ссылкам
• Отслеживайте источник установки

2. Совместная работа с бэкендом:

{
"url": "https://app.com/product/123",
"ios_store_id": "123456789",
"android_package": "com.yourapp"
}


3. Тестирование:

# Android
adb shell am start -W -a android.intent.action.VIEW -d "https://yourdomain.com/product/123"

# iOS
xcrun simctl openurl booted "https://yourdomain.com/product/123"



Лучшие практики:

• Используйте Firebase Dynamic Links для кроссплатформенного решения
• Поддерживайте веб-версии всех deep link-страниц
• Документируйте все схемы URL для команды

Какие библиотеки для deep links вы используете? Делитесь опытом в комментариях 💬

🐸 Библиотека мобильного разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
3
⚠️ 5 ловушек Swift, которые вы не заметите, пока не станет слишком поздно

1️⃣ Сильные циклы ссылок в замыканиях

Замыкания по умолчанию захватывают self. Если вы не используете [weak self], вы можете получить цикл удержания и утечку памяти.

class ProfileViewModel {
var onUpdate: (() -> Void)?

func setup() {
onUpdate = {
self.doSomething() // ⚠️ This captures self strongly
}
}
}


Исправление:

onUpdate = { [weak self] in
self?.doSomething()
}


2️⃣ Принудительное развертывание Optional

Это очевидно, но все еще часто встречается это в коде:

let name: String? = getName()
print(name!) // Crashes if nil


Даже «безопасные» места могут подвести вас — например, повторное использование ячеек в UITableView.

Вместо этого используйте guard let или if let. Никогда не доверяйте данным слепо.

3️⃣ Неявно разворачиваемые Optional (String!)

Они кажутся удобными. Но они вызывают сбой, как и !, если не настроены правильно.

var token: String!
print(token.count) // If token is nil, boom.


По умолчанию используется ?. Используйте ! только в том случае, если вы абсолютно уверены, что он инициализирован перед использованием (например, инжектирован через сториборд).

4️⃣ Не помеченные как final классы

По умолчанию каждый класс в Swift может быть подклассом. Это может привести к снижению производительности из-за динамической диспетчеризации.

Используйте final, когда подклассы не нужны. Компилятор будет оптимизировать код лучше.

final class UserManager {
// Now faster method calls, no subclassing allowed
}


5️⃣ Отсутствие weak у делегатов

Классическая ошибка в конфигурациях MVC или MVVM.

protocol MyDelegate: AnyObject {
func didUpdate()
}

class MyController {
var delegate: MyDelegate? // Should be weak
}


Всегда объявляйте свойства делегатов как weak, чтобы избежать циклов удержания:

weak var delegate: MyDelegate?


Какие ошибки чаще вам встречаются? Пишите в комментариях 💬

🐸 Библиотека мобильного разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍3🔥1😁1
🏦 Интеграция платежных систем на уровне банковской инфраструктуры

Конкурентоспособность банков и финтех-компаний все больше зависит от скорости и надежности платежей. Сегодня интеграция с национальными системами быстрых платежей вроде SEPA Instant — необходимость для выживания, а не просто полезная надстройка.

Зачастую подключение к таким системам — сложный технологический проект, который требует глубокого понимания как банковской инфраструктуры, так и современных подходов к разработке высоконагруженных систем.

👉 Читать статью

🐸 Библиотека мобильного разработчика

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Системы типов в языке — какие бывают и чем отличаются

Классификация делит языки на статически типизированные и динамически типизированные.

В статически типизированном языке каждая переменная имеет определенный тип на всем протяжении жизни, он не может измениться во время выполнения. То есть все типы известны ещё на этапе написания кода.

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

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

И что лучше?

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

Что предпочитаете вы? Голосуйте и пишите своё мнение в комментариях 💬

❤️ — статическая
👍 
динамическая

🐸 Библиотека мобильного разработчика 

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
14🎉2👍1
🎁 Топ вакансий для мобильных разработчиков за неделю

Senior Flutter разработчик — 215 000 ₽, удалёнка

iOS Developer (Сообщества) — от 250 000 ₽, удалёнка

Flutter Developer — от 200 000 ₽, офис (Москва)

Старший iOS-разработчик — от 300 000 до‍ 540 000 ₽, гибрид (Москва)

Flutter-developer — от 300 000 до 540 000 ₽, удалёнка

➡️ Еще больше топовых вакансий — в нашем канале Mobile jobs

🐸 Библиотека мобильного разработчика

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🎁 pod install --repo-update – надежный способ избежать "кэш-проблем" с CocoaPods

Эта команда гарантирует, что перед установкой:

• Локальный репозиторий CocoaPods синхронизируется с удаленным
• Вы получаете актуальные версии всех зависимостей
• Исключаются проблемы с устаревшим кэшем

⚠️ Важно знать:

Для экономии времени в CI можно использовать pod install --repo-update --verbose (лог поможет отладить проблемы)

Альтернатива для "чистого" старта:

rm -rf ~/.cocoapods/repos && pod setup


Лайфхак: Добавьте в ваш Fastfile:

lane :setup_pods do
sh "pod install --repo-update"
end


А вы часто сталкиваетесь с проблемами CocoaPods? Делитесь в комментариях своими способами решения 💬

🐸 Библиотека мобильного разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Последний шанс залутать курсы Proglib Academy с выгодой 40% и пожизненным доступом.

До 1 августа действует скидка на курсы по математике для Data Science, алгоритмам и структурам данных, обновлённому Python, frontend-разработке с нуля, основам IT для непрограммистов, базовым моделям ML, а также архитектурам и шаблонам проектирования.

Выбираем и забираем 👈

P.S. Акция не распространяется на курсы «AI-агенты для DS-специалистов» и «ML для старта в Data Science».
🌛 Как сделать ваше веб-приложение доступным в офлайн-режиме

В этом материале автор разберёт, как работают PWA и WebView в офлайн-режиме, посмотрит на инструменты, которые помогают реализовать такую функциональность, и в завершении поделиться примером: какую технологию он выбрал для календаря и как внедрил офлайн-режим на практике.

👉 Читать статью

🐸 Библиотека мобильного разработчика

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2🔥2
🔔 Настройка push-уведомлений в мобильных приложениях

👾 Firebase Cloud Messaging (Android)

1. Добавьте зависимости:

implementation 'com.google.firebase:firebase-messaging:23.1.0'


2. Регистрация токена:

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
// Отправьте токен на ваш сервер
}
}


3. Обработка входящих сообщений:

class MyFirebaseService : FirebaseMessagingService() {
override fun onMessageReceived(message: RemoteMessage) {
// Создайте и отобразите уведомление
}
}


👨‍💻 Apple Push Notification Service (iOS)

1. Настройка в Xcode:

• Включите Push Notifications в Capabilities
• Зарегистрируйте сертификаты в Developer Center

2. Запрос разрешений:

UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound, .badge]) { granted, error in
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}


3. Обработка токена устройства:

func application(_ application: UIApplication, 
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
// Отправьте токен на сервер
}


🚀 Продвинутые функции

1. Группировка уведомлений (Android):

NotificationCompat.Builder(context, CHANNEL_ID)
.setGroup("news_group")
.setGroupSummary(true)


2. Действия в уведомлениях (iOS):

let action = UNNotificationAction(
identifier: "replyAction",
title: "Ответить",
options: [.foreground])


3. Глубокая навигация:

val pendingIntent = NavDeepLinkBuilder(context)
.setGraph(R.navigation.main_nav)
.setDestination(R.id.detailsFragment)
.createPendingIntent()


Какие лучшие практики по push-уведомлениям используете вы? Делитесь в комментариях 💬

🐸 Библиотека мобильного разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
2🥱2
✏️ Чек-лист: полный контроль качества

Перед релизом или крупным обновлением пройдитесь по этому списку, чтобы избежать критических ошибок и негативных отзывов.

✔️ Основные проверки

Тестирование на 5+ реальных устройствах (включая старые модели)
Проверка работы приложения при плохом интернет-соединении
Анализ потребления батареи в фоне
Тестирование на "ломанных" прошивках (для Android)

✔️ Технический аудит

Проверка крэш-репортов (Firebase/Sentry)
Оптимизация размера APK/IPA (<100MB для Google Play, <200MB для App Store)
Проверка скорости загрузки контента (Lottie-анимации, тяжелые изображения)
Тестирование deep links и универсальных ссылок

✔️ UI/UX валидация

Соответствие гайдлайнам Material Design/Human Interface
Проверка адаптивности на экранах от 4.7" до 7.9"
Тестирование темной/светлой темы
Валидация тач-зоны всех интерактивных элементов

✔️ Процесс публикации

Подготовка release notes на 3+ языках
Проверка возрастного рейтинга и контент-фильтров
Включение всех необходимых разрешений в манифест
План отката на предыдущую версию

Какие важные пункты мы забыли? Пишите в комментариях 💬

🐸 Библиотека мобильного разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍1
🏦 Интеграция платежных систем на уровне банковской инфраструктуры

В карточках рассказали, как создать надежную платежную систему, которая может обрабатывать тысячи транзакций ежедневно с минимальным количеством простоев и наивысшим уровнем отказоустойчивости.

➡️ Подробнее в статье

🐸 Библиотека мобильного разработчика

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
2