Рідний інтерфейс користувача на основі бекенда в редакторському додатку для iOS.js

68
Контакты исчезли после обновления iOS 15.4.1

Як швидко інтегрувати і спочатку відтворити зміст формату статті в своєму мобільному додатку, практично без завантаження проекту і всього за кілька рядків коду? У цій статті я опишу наш спосіб вирішення такої проблеми.

Матеріал може зацікавити будь-які мобільні продуктові бригади, де є потреба в макеті на основі бекенда, а зміст програми — статті, угоди, документи, стандартні картки, списки і т.д.

Про інструмент

Інструментом, про який йде мова, є фреймворк Editor.js Kit, створений нашою командою. Він перетворює дані JSON редактора.js формату в рідний мобільний макет 👇
Рідний інтерфейс користувача на основі бекенда в редакторському додатку для iOS.js - Украина, Польша, Германия.
Фреймворк розміщений з відкритим вихідним кодом і доступний на github для iOS (Swift) і Android (Kotlin). В рамках цієї статті з практичної сторони розкривається тільки частина iOS.

Передісторія

Пару років тому перед нашою командою стояло завдання малювати новинні статті, угоди користувачів, екрани опису продукції та інші відформатовані масиви тексту в мобільному додатку, чергуючи з картинками, відформатованими посиланнями і списками. Загалом, екрани мають формат статті, як на TJ/VC. Контент повинен був роздавати бекендом, і вже конкретний клієнт (web / iOS / Android) форматує і надає його відповідно до ідей хорошої UX-платформи і відчуття краси.

Завдання, з одного боку, тривіальне. Але, по-перше, екрани з таким контентом зустрічаються повсюдно практично у всіх додатках, і було б добре придумати багаторазове універсальне рішення. А по-друге, можливість взяти UITextView / WKWebView і годувати його html макетом нам не підходить, так як дані повинні бути легкими, а макет повинен бути рідним.

Було прийнято рішення: ми п’ємо рамки.

Формат даних: Редактор.js

При виборі формату створення, зберігання і передачі контенту були враховані три фактори:

  • Команда редакторів повинна створювати статті з форматуванням в якомусь зручному веб-редакторі;
  • БЕКЕНД API повинен мати можливість приймати написану статтю зі збереженням форматування, зберігати її і поширювати по всіх клієнтах на будь-якій платформі в єдиному форматі;
  • Мобільний клієнт повинен прийняти зміст статті, проаналізувати її і передати її на батьківщині.

Довго ми не думали: натрапили на Редактора.js. На думку авторів з команди CodeX, цей інструмент використовується для написання статей про vc.ru, TJ і DTF.

Основною концепцією є блокова структура і чисті дані у вигляді JSON на виході. На відміну від більшості редакторів, де користувач працює з текстом всередині єдиної редагованої обгортки, в Редакторі.js кожен структурний елемент статті — блок — є окремим елементом, який можна редагувати. Блоки можуть бути будь-якими: абзацами, заголовками, цитатами, списками, зображеннями, твітами, опитуваннями тощо.

Підтримувані блоки

З поля фреймворк підтримує сім типів блоків: заголовок, абзац, зображення з підписом, посилання, список пронумерований / маркірований аркуш, роздільник і чистий html.
Рідний інтерфейс користувача на основі бекенда в редакторському додатку для iOS.js - Украина, Польша, Германия.

Розбір вмісту

Дані JSON можна давати як з БЕКЕНД API, так і локально лежати в пакеті або пам’яті смартфона — підготовка до його використання буде такою ж і максимально простою в будь-якому випадку. Коротше кажучи:

Дані JSON 'data: Data' перетворюються на список блоків, готових до відображення, нехай myBlocks = спробуйте EJKit.shared.decode(data: data)

Підключення до екрана

Для відображення екранів прокрутки ми майже завжди використовуємо UICollectionView замість UITableView через більшу гнучкість макета. Тому підтримка колекції була зроблена в першу чергу. Любителів столу заспокоюють — їх підтримка легко додається адаптером відповідно до зразкового збору.

Існує два основних сценарії інтеграції макета на екрані. По-перше, коли ваш екран складається тільки з редактора.js блоків. Робиться це максимально просто через адаптер:

import EditorJSKit /// Не забудьте відповідати класу ViewController': UICollectionDataSource' класу ViewController: UIViewController, EJCollectionDataSource { /// Китовий екземпляр let kit = EJKit.shared lazy var collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UICollectionViewFlowLayout()) ледачий var адаптер = EJCollectionViewAdapter(collectionView: collectionView: collectionView) /// Список блоків, які ми аналізуємо var блоків: EJBlocksList? /// реалізація EJCollectionDataSource протоколу var data: EJBlocksList? { blocks } /** */ override func viewDidLoad() { super.viewDidLoad() adapter.dataSource = self let data: Data // your json data у форматі Editor.js blocks = try EJKit.shared.decode(data: data) collectionView.reloadData() } } }

Другий сценарій полягає в тому, якщо вам потрібно вставити блоки в існуючий екран з колекцією, в будь-якому місці. Для цього зручно використовувати EJCollectionRenderer, який безпосередньо реалізує dataSource і делегує методи збору і дозволяє додавати блоки в колекцію в будь-якому зручному порядку. Прикладом такої інтеграції є Readme на github.

Налаштування стилів

У більшості випадків кожен проект має свою систему дизайну, тобто свої розміри шрифтів, відступи і кольори.

Розглянемо основні налаштування на прикладі заголовків:

{ "тип": "заголовок", "дані": { "текст": "Заголовок 1", "рівень": 1 } }

Скажімо, ми хочемо змінити розмір шрифту для кожного рівня заголовка, вирівняти їх по центру та значно збільшити відступ у верхній та нижній частині. Протокол EJHeaderBlockStyle відповідає за стиль заголовка, який потрібно реалізувати:

struct CustomHeaderStyle: EJHeaderBlockStyle { let alignment: NSTextAlignment = .center /** */ func font(forHeaderLevel level: Int) -> UIFont { switch level { case 1: return UIFont.systemFont(ofSize: 30, вага: .bold) case 2: return UIFont.systemFont(ofSize: 24, вага: .bold) за замовчуванням: повернення UIFont.systemFont(ofSize: 20, вага: .semibold) } } }/** */ func topInset(forHeaderLevel level: Int) -> CGFloat { рівень повернення == 1 ? 10 : 6 } /** */ func bottomInset(forHeaderLevel level: Int) -> CGFloat { рівень повернення == 1 ? 20 : 12 } } }

З’єднайте стиль:

EJKit.shared.set(стиль: CustomHeaderStyle(), для: EJNativeBlockType.header)

В результаті отримуємо призначене форматування без будь-яких змін в коді подання або в JSON даних:

Рідний інтерфейс користувача на основі бекенда в редакторському додатку для iOS.js - Украина, Польша, Германия.

Настроювані блоки

Абсолютно будь-який блок можна вбудувати в полотно прокрутки, і для цього не потрібно писати занадто багато коду.

Кожен блок JSON являє собою два поля верхнього рівня: тип (тип блоку) і дані (вміст JSON, який залежить від типу блоку). Наприклад, давайте придумаємо і зробимо виноску:

{ "тип" : "виноска", "дані" : { "emoji": "🙀", "text" : "Це власний блок, який був легко інтегрований з кількома рядками коду." } }

Перш за все, давайте створимо користувальницький тип зчислення для наших власних блоків, відразу додавши туди виноску:

enum CustomBlockType: String, EJAbstractBlockType { case виноски }

Потім напишемо модель для поля даних, важливо поставити протоколи:

public struct CalloutBlockContentItem: EJAbstractBlockContentItem { let text: String let emoji: String }

Наступним кроком є запис стилю для нашої виноски, а також впровадження EJBlockStyle:

struct CalloutBlockStyle: EJBlockStyle { // жовтий фонColor = UIColor(червоний: 1, зелений: 0.78, синій: 0, альфа: 0.2) нехай cornerRadius: CGFloat = 6 let lineSpacing: CGFloat = 10 let font = UIFont.systemFont(ofSize: 16) let textColor = UIColor.black let emojiFont = UIFont.systemFont(ofSize: 24) }

І, звичайно ж, макет. У спрощеному вигляді, без деталей, реалізація виду виглядає так:

остаточний клас CalloutBlockView: UIView, EJBlockView { private let emoji = UILabel() private let label = UILabel() /** Label тексти пісень і застосувати стиль */ func conwew(withItem пункт: CalloutBlockContentItem, стиль: EJBlockStyle?) { emoji.text = item.emoji label.text = item.text guard let style = style as? CalloutBlockStyle else { return } backgroundColor = style.backgroundColor layer.cornerRadius = style.cornerRadius emoji.font = style.emojiFont label.font = style.font label.textColor = style.textColor } /** Тут вам потрібно розрахувати розмір блоку з урахуванням його стилю */ статичний func estimatedSize(для пункту: CalloutBlockContentItem, стиль: EJBlockStyle?, обмеженняWidth: CGFloat) -> CGSize { return CGSize (ширина: обмеженняWidth, height: 100) }

Останній крок: підключіть створений блок до EJKit.

Прив'язати елементи блоку в єдиний скелет let calloutBlock = EJCustomBlock ( тип: CustomBlockType.виноска, contentClass: BlockContent.Single<CalloutBlockContentItem>.self, viewClass: CalloutBlockView.self) // Реєстрація блоку EJKit.shared.register(customBlock: виноскаBlock) // Реєстрація стилю блоку EJKit.shared.style.set(стиль: CalloutBlockStyle(), для: CustomBlockType.callout)

Готовий! Подивіться на результат у вигляді світло-жовтої виноски з шокованою кішкою в центрі екрану:

Рідний інтерфейс користувача на основі бекенда в редакторському додатку для iOS.js - Украина, Польша, Германия.

Недоліки сьогодні

  • Підтримується тільки відображення контенту, немає можливості редагування блоків безпосередньо з клавіатури на смартфоні.
  • Немає взаємодії з вмістом блоків (за винятком натискання на гіперпосилання і відформатовані посилання). Звичайно, ви можете написати свій власний власний блок і зареєструвати там все, що забажає ваше серце. Але немає архітектури на рівні фреймворку для підтримки інтерактивного.
  • Стилі для семи типів блоків, які підтримуються з коробки, не є вичерпними. Текст, крім кольору, шрифту і відступу, має, як мінімум, міжрядковий інтервал, кернінг і т.д. Але знову ж таки, ніщо не заважає вам переосмислити той чи інший блок або стиль для системи дизайну вашого проекту.

Висновки

Редактор.js Kit добре підходить для тих, кому потрібно реалізувати макет на основі бекенда в мобільному продукті хоча б на декількох екранах. Маючи досить невеликі інвестиції в часі, ви можете інтегрувати естетичний рідний інтерфейс користувача у ваш додаток відповідно до вашого коду дизайну, не розщеплюючи проект зі сторонніми залежностями.

Поряд з безкодовими і низькокодовими продуктами, наше рішення покликане скоротити час, який команда витрачає на проектування тривіальних завдань, а програміста на написання коду котельні, що особливо важливо для стартапів і команд на етапах створення MVP продукту.

Всі бажаючі — ласкаво просимо до нас на github: iOS і Android.

Команда Upstarts.work працювала над фреймворком

Автори та дописувачі: ВадимРусланІванІсрапільОлександр

Редактор.js – Команда CodeX

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *