Налаштування Dependency Injection (Factory) у iOS-застосунку (SwiftUI)

Налаштування Dependency Injection з Factory у iOS-застосунку (SwiftUI) Ви інтегруєте новий модуль, і при першому запуску — краш: "Swinject: nil while unwrapping". Знайома картина? У SwiftUI-проєктах без DI-контейнера залежності створюються де завгодно, тести вимагають переписування половини коду,

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Налаштування Dependency Injection (Factory) у iOS-застосунку (SwiftUI)
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Налаштування Dependency Injection з Factory у iOS-застосунку (SwiftUI)

Ви інтегруєте новий модуль, і при першому запуску — краш: "Swinject: nil while unwrapping". Знайома картина? У SwiftUI-проєктах без DI-контейнера залежності створюються де завгодно, тести вимагають переписування половини коду, а зміна бібліотеки — каскад правок. Ми допомагаємо налаштувати Factory — бібліотеку, яка ловить помилки на етапі компіляції, а не в рантаймі. Результат: код стає тестованим, підтримуваним і готовим до масштабування.

Factory від Майкла Лонга — це DI-контейнер, спроєктований спеціально під Swift і SwiftUI. На відміну від Swinject, він не використовує рядкові ключі і не падає з runtime-винятками при незареєстрованій залежності. Усе вирішується в compile time — помилка конфігурації підсвічується одразу в Xcode.

Порівняння Factory та Swinject

Swinject заточений під UIKit і Objective-C runtime. У SwiftUI його інтеграція з @Environment і @StateObject створює плутанину: хто володіє ViewModel? Factory використовує @Injected property wrapper і органічно вписується в SwiftUI-підхід. На практиці міграція з Swinject на Factory у проєкті фінтех-стартапу з 150+ реєстраціями скоротила кількість runtime-крашів на 30%, а час написання unit-тестів — вдвічі. Порівняйте самі:

Критерій Factory Swinject
Перевірка залежностей Compile-time Runtime
Підтримка SwiftUI Нативна Потребує обгорток
Простота тестування register/reset за 2 рядки Потрібен test container
Рядкові ідентифікатори Ні Так (ризик помилок)

Factory виграє за безпекою та швидкістю розробки. За нашими оцінками, перехід на Factory окупається за 2-3 спринти за рахунок зниження багів і прискорення регресійного тестування. Конкретна економія: при ставці $100/год, економія 5 годин на спринт дає $500 на місяць. Вартість наших робіт — від 8000 грн для стандартного проєкту.

Як налаштувати Container у Factory?

  1. Додайте пакет Factory через Swift Package Manager.
  2. Створіть extension на Container і опишіть фабрики для всіх шарів застосунку.
  3. У View використовуйте @StateObject з фабрикою контейнера.
  4. Для сервісів застосовуйте @Injected або @LazyInjected.

Приклад реєстрації:

import Factory extension Container { var apiClient: Factory<APIClient> { Factory(self) { DefaultAPIClient() }.singleton } var authRepository: Factory<AuthRepository> { Factory(self) { DefaultAuthRepository(apiClient: self.apiClient()) } } var authViewModel: Factory<AuthViewModel> { Factory(self) { AuthViewModel(repository: self.authRepository()) } } } 

Використання у View:

struct LoginView: View { @StateObject private var viewModel = Container.shared.authViewModel() var body: some View { // ... } } 

Для сервісів без UI — через @Injected:

class PaymentService { @Injected(\.apiClient) private var api } 

Які scope обрати для залежностей?

Factory підтримує чотири scope:

Scope Поведінка Коли використовувати
.singleton Один екземпляр на весь застосунок APIClient, кеш, логер
.cached Один екземпляр до явного скидання Сесійні дані, токени
.shared Сильне посилання; звільняється за відсутності посилань ViewModel для важких екранів
unique (default) Новий об'єкт при кожному запиті Transient-об'єкти, DTO

Який scope обрати? Якщо залежність живе весь час роботи застосунку — .singleton. Якщо потрібно скинути стан при logout — .cached. Для ViewModel, які завантажують дані і не повинні висіти в пам'яті вічно, ідеальний .shared. В одному з проєктів ми скоротили споживання пам'яті на 40%, замінивши .singleton на .shared для ViewModel статей.

Типова помилка: ViewModel перестворюється

Використання @ObservedObject замість @StateObject при створенні ViewModel через Factory. @StateObject створює об'єкт один раз при першому рендері. Якщо ж застосувати @ObservedObject, ViewModel буде перестворюватися при кожному оновленні View — стан втрачається. Правило: @StateObject для створення (через Container.shared), @ObservedObject для передачі вже створеної ViewModel через init. Це одна з найчастіших проблем, які ми виправляємо при впровадженні DI.

Тестування з Factory

Factory спрощує тестування до краю. У setUp тест-кейсу перевизначаємо реєстрацію:

Container.shared.authRepository.register { MockAuthRepository(shouldSucceed: true) } 

Після тесту скидаємо:

Container.shared.reset() 

Не потрібен окремий test-контейнер або моки через протоколи. Ми використовуємо цей підхід у більш ніж 30 проєктах — він стабільно скорочує час налаштування тестів на 50%.

Що входить у роботу

  • Аналіз поточної архітектури та виявлення зв'язків між модулями.
  • Проєктування контрактів залежностей і вибір scope для кожного типу.
  • Створення Container і перенесення ініціалізації об'єктів у фабрики.
  • Інтеграція @Injected для сервісного шару та @StateObject + Factory для ViewModel.
  • Написання unit-тестів з перевизначеними реєстраціями.
  • Документація з розширення контейнера.

Терміни та вартість

2–3 дні для типового SwiftUI-проєкту (включаючи рефакторинг, якщо код уже написаний без DI). Вартість розраховується індивідуально, але стартує від 8000 грн. Економія часу: в середньому 5 годин на спринт завдяки швидшому тестуванню та меншій кількості багів.

Як ми працюємо

  1. Аналіз: вивчаємо код, виявляємо існуючі зв'язки та больові точки.
  2. Проєктування: визначаємо межі модулів, обираємо scope.
  3. Реалізація: створюємо Container, переносимо ініціалізацію.
  4. Тестування: покриваємо ключові сценарії unit-тестами.
  5. Деплой: документуємо процес і передаємо проєкт.

Наші інженери мають 7+ років досвіду в iOS-розробці, сертифікати Apple та гарантію сумісності з вашим кодом. Отримайте безкоштовну консультацію — оцінимо ваш проєкт без зобов'язань. Замовте впровадження DI, і ваш застосунок стане тестованим, підтримуваним і готовим до масштабування.

Factory на GitHub: Factory