Ми розробляємо кастомні розширення клавіатур для iOS — від простих смайликових до повноцінних з автокорекцією та підтримкою кількох мов. Custom Keyboard Extension — єдиний тип розширення, який працює в усіх застосунках одразу, але саме через це його найскладніше зарелізити: Apple вимагає чіткого дотримання правил безпеки, інакше — відхилення. Наш досвід включає понад 10 успішних проєктів, і ми гарантуємо проходження рев'ю App Store з першого разу.
Чому Custom Keyboard Extension — найвимогливіший тип розширення?
Архітектурно клавіатура живе в ізольованому процесі через UIInputViewController. Вона не має прямого доступу до UserDefaults основного застосунку без App Groups, мережа працює тільки при увімкненому прапорці RequestsOpenAccess, а системні поля (наприклад, з паролями) блокують контекст введення.
Що відбувається, якщо не налаштувати App Group?
Перша типова помилка: розробник налаштовує App Group для передачі налаштувань з основного застосунку в розширення, але забуває додати group в Capabilities самого Extension target — не тільки основного застосунку. Xcode не попереджає. Краш приходить вже на пристрої у вигляді nil при читанні UserDefaults(suiteName:). Ми налаштовуємо App Group на обох target'ах одразу і перевіряємо доступність suite в коді.
Як правильно вказати RequestsOpenAccess?
Apple вимагає, що якщо прапорець RequestsOpenAccess виставлений в YES, клавіатура зобов'язана явно описати в Privacy Policy, як використовуються дані введення. Якщо опис розпливчастий або його немає — відхилення за 5.1.1 (Data Collection and Storage). При цьому якщо прапорець NO, мережеві запити з розширення мовчки впадуть без жодних помилок у логах. Ми завжди документуємо політику і перевіряємо консистентність між прапорцем і функціоналом.
Ключі, які потрібно відстежувати в Info.plist розширення
| Атрибут | Значення | Опис |
|---|---|---|
IsASCIICapable |
false | Підтримка тільки ASCII; false для повного набору символів |
PrefersRightToLeft |
false | Напрямленість тексту; false для LTR |
PrimaryLanguage |
en-US | Основна мова для автокорекції |
RequestsOpenAccess |
true/false | Доступ до мережі та повний контекст введення; true вимагає Privacy Policy |
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IsASCIICapable</key>
<false/>
<key>PrefersRightToLeft</key>
<false/>
<key>PrimaryLanguage</key>
<string>en-US</string>
<key>RequestsOpenAccess</key>
<true/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.keyboard-service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).KeyboardViewController</string>
</dict>
Як влаштована нормальна Custom Keyboard
UIInputViewController надає textDocumentProxy — об'єкт, через який клавіатура взаємодіє з текстовим полем host-застосунку. Вставка тексту: textDocumentProxy.insertText("a"). Видалення символу: textDocumentProxy.deleteBackward(). Перемикання мови: advanceToNextInputMode(). Закриття клавіатури: dismissKeyboard().
Важливий момент: textDocumentProxy.documentContextBeforeInput і documentContextAfterInput повертають текст навколо курсора — але не завжди. У деяких полях (protected text fields, поля з атрибутами isSecureTextEntry) proxy повертає nil. Це потрібно обробляти явно, інакше будь-яка логіка автокорекції або передбачення слів зламається на полях з паролями.
Проблема висоти клавіатури
Системна клавіатура адаптується під Safe Area автоматично. Кастомна — ні. Висоту потрібно задавати через heightConstraint на inputView, і перераховувати при зміні орієнтації пристрою:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let newHeight: CGFloat = view.bounds.width > view.bounds.height ? 180 : 256
if heightConstraint?.constant != newHeight {
heightConstraint?.constant = newHeight
view.layoutIfNeeded()
}
}
Без явного перерахунку на iPhone в landscape-режимі клавіатура або обрізається, або перекриває контент неправильною висотою.
Збереження стану між сесіями
Розширення не має постійного стану в пам'яті — процес завершується разом із введенням. Налаштування (розкладка, тема, автокорекція) потрібно зберігати в UserDefaults через App Group. Дані побільше (навчений словник, emoji-історія) — в shared CoreData container або файлі в shared container через FileManager.containerURL(forSecurityApplicationGroupIdentifier:).
Порівняння підходів до зберігання словника:
| Критерій | UserDefaults (App Group) | CoreData (shared container) |
|---|---|---|
| Швидкість читання/запису | Висока (синхронно) | Середня (асинхронно, з контекстом) |
| Розмір даних, що зберігаються | Обмежений (~512 КБ) | Практично без обмежень |
| Пошук та фільтрація | Ні (ключ-значення) | Так (запити та предикати) |
| Приклад | Тема, розкладка | Навчений словник, історія введення |
Що входить у розробку кастомної клавіатури?
- Повний аудит вимог та складання Privacy Policy відповідно до правил Apple.
- Реалізація розширення з нуля або доопрацювання існуючого (Swift, SwiftUI/UIKit).
- Налаштування App Group, shared container, CoreData (якщо потрібен словник).
- Адаптація під iPad та різні орієнтації.
- Тестування на реальних пристроях через TestFlight, включаючи перевірку в полях UISearchBar, UITextView з
isEditable = false, Safari Address Bar. - Допомога у проходженні рев'ю App Store (перевірка за пунктами 4.2 та 5.1).
- Документація та рекомендації щодо подальшої підтримки.
Терміни та вартість
Термін розробки — від 2 до 4 тижнів залежно від функціоналу (автокорекція, багатомовність, навчання словника). Вартість розраховується індивідуально після попереднього аналізу вимог. Зв'яжіться з нами для консультації — оцінимо ваш проєкт безплатно.
Чому важливо правильно налаштувати RequestsOpenAccess?
Якщо прапорець встановлений в YES, ви отримуєте повний доступ до контексту введення та можливість виконувати мережеві запити. Без цього не можна реалізувати перевірку орфографії через зовнішні сервіси або завантажувати смайлики з сервера. Але Apple вимагає явного документа з політикою обробки даних, інакше — відмова. Якщо прапорець NO, клавіатура безпечніша (немає мережі), але функціонал обмежений. Ми допомагаємо вибрати оптимальну конфігурацію під завдання продукту.
Як уникнути відхилення на рев'ю App Store?
Ми проходимо рев'ю з першого разу в 95% випадків. Для цього:
- Перевіряємо консистентність між заявленим функціоналом та реалізацією.
- Готуємо детальну Privacy Policy, якщо прапорець
RequestsOpenAccessактивний. - Тестуємо поведінку в захищених полях та після перемикання розкладок.
- Переконуємося, що клавіатура не збирає дані без явної згоди. Зв'яжіться з нами — і ми проведемо безплатний аудит вашого проєкту на готовність до публікації.
Додаткова інформація: UIInputViewController — офіційна документація Apple.







