Хочешь быть в курсе самых свежих новостей, полезных советов и уникального контента? Тогда наш канал — именно то, что тебе нужно!
Что ты найдёшь в нашем канале:
Присоединись к нашему дружному сообществу и будь на шаг впереди! Подписывайся на Swift от Дена и открывай новые горизонты вместе с нами!
Не упустите шанс стать частью нашей команды!
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Swift от Дена
IOS разработчик. Swift/SwiftUI
GitHub - https://github.com/Den1Doc
App Store - https://apps.apple.com/ru/app/%D0%BC%D0%BE%D1%8F-%D1%82%D0%B0%D1%87%D0%BA%D0%B0-%D1%82%D1%80%D0%B5%D0%BA%D0%B5%D1%80-%D0%B0%D0%B2%D1%82%D0%BE/id6739165836
GitHub - https://github.com/Den1Doc
App Store - https://apps.apple.com/ru/app/%D0%BC%D0%BE%D1%8F-%D1%82%D0%B0%D1%87%D0%BA%D0%B0-%D1%82%D1%80%D0%B5%D0%BA%D0%B5%D1%80-%D0%B0%D0%B2%D1%82%D0%BE/id6739165836
👍9🗿4🔥2👀1
Всем привет! На сайте Apple Developer появился пост о новом API для приложений, которое предлагает расширенные возможности управления встроенными покупками. Речь идет о партнерской программе для мини-приложений в App Store - шаге, который открывает новые возможности для разработчиков крупных платформ.
Суть программы и основные требования:
Apple официально анонсировала программу для мини-приложений: встроенных компонентов, созданных на HTML5, JavaScript и других одобренных языках. Ключевое условие: эти мини-приложения не должны контролироваться разработчиком основного приложения, что предполагает создание открытых экосистем.
Для участия необходимо соответствие нескольким требованиям:
Преимущества для разработчиков:
Основной бенефит программы: сниженная до 15% комиссия за встроенные покупки в мини-приложениях. Это существенно ниже стандартных 30% и создает экономические стимулы для развития платформенных решений.
Программа открывает возможности для:
Бизнес-перспективы:
Пример Tencent с WeChat демонстрирует потенциал таких экосистем. Программа Apple позволяет легализовать подобные модели в iOS-экосистеме, создавая новые монетизационные каналы. Это может стимулировать появление суперапов - приложений-платформ с множеством встроенных сервисов.
Технические аспекты реализации:
Разработчикам необходимо предусмотреть:
Партнерская программа Apple для мини-приложений представляет собой стратегический шаг в развитии iOS-экосистемы. Она открывает возможности для создания платформенных решений и новых моделей монетизации, но требует тщательной технической реализации и соблюдения строгих правил. Для крупных разработчиков это шанс построить комплексные экосистемы, в то время как небольшие студии могут найти свою нишу в создании контента для таких платформ.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍9👀6😁2 1
Сталкивались с ситуацией, когда в SwiftUI кнопка или любая другая View выглядит кликабельной, но не реагирует на нажатия? Это частая проблема, и решение проще, чем кажется.
В чем проблема:
SwiftUI по умолчанию определяет область нажатия только по видимому контенту. Если у вас:
То интерактивная область может быть меньше, чем сама View.
Простое решение:
Добавьте модификатор
.contentShape() чтобы явно задать область нажатия:// Было: не работает
Rectangle()
.stroke(Color.blue, lineWidth: 2)
.frame(width: 100, height: 50)
.onTapGesture {
print("Тап!")
}
// Стало: работает
Rectangle()
.stroke(Color.blue, lineWidth: 2)
.frame(width: 100, height: 50)
.contentShape(Rectangle())
.onTapGesture {
print("Тап!")
}
Как это работает:
Модификатор
.contentShape() явно задает область, в которой должны распознаваться жесты, независимо от визуального представления. Модификатор принимает несколько вариантов значений:.contentShape(Rectangle()) // Прямоугольная область
.contentShape(Circle()) // Круглая область
.contentShape(Capsule()) // Капсульная область
// Разные стили для разных случаев
.contentShape(Rectangle(), style: FillStyle())
Параметры FillStyle:
Пример:
VStack {
Text("Первый элемент")
Text("Второй элемент")
}
.contentShape(Rectangle()) // Общая кликабельная область для всего стека
.onTapGesture {
print("Тап по любой части VStack")
}
Path { path in
path.addRect(CGRect(x: 0, y: 0, width: 100, height: 100))
path.addRect(CGRect(x: 25, y: 25, width: 50, height: 50))
}
.stroke(Color.blue, lineWidth: 2)
.contentShape(
Rectangle(),
style: FillStyle(eoFill: true) // Только внешний прямоугольник кликабелен
)
.onTapGesture {
print("Тап по внешней области")
}Модификатор
contentShape() - это надежное решение проблем с интерактивностью в SwiftUI. Он позволяет точно контролировать, какая область View должна реагировать на жесты, что особенно важно при работе с кастомными фигурами и сложными layout.Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Всем привет! Пока все увлекаются быстрым «вайбкодингом» с ИИ, появилось противоположное движение: Deep Coding. Это подход, где разработчик сохраняет полный контроль над архитектурой и качеством кода.
В чем суть Deep Coding?
Если «вайбкодинг» - это потоковое генерирование кода с доверием ИИ, то Deep Coding - это осознанное проектирование, где ИИ выступает лишь помощником в реализации деталей.
Как это работает:
Этап 1: архитектурное проектирование.
Прежде чем просить ИИ написать код, вы самостоятельно проектируете каркас будущей системы. Это как архитектор, который сначала создает чертежи здания, а только потом строители начинают работу.
Что конкретно делаете сами:
Этап 2: контроль реализации.
Вы используете ИИ для написания конкретных методов, но проверяете каждую строчку кода:
Преимущества Deep Coding:
Почему это важно именно сейчас:
Рынок начинает ценить не скорость написания кода, а способность создавать поддерживаемые и масштабируемые системы. Junior может сгенерировать код, но только Senior способен спроектировать архитектуру.
Deep Coding - это не отказ от современных инструментов, а разумное их использование. Сохраняйте архитектурное мышление, контролируйте качество кода, и пусть ИИ будет вашим помощником, а не заменой профессиональным навыкам.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍18❤11🔥5👀2 2✍1
💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни!
Чтобы принять участие, нужно:
🔹 Подписаться на канал.
🔹 Нажать кнопку «Участвую!».
Чтобы принять участие, нужно:
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Мобильный трудоголик
🍏 🏋️ Мое приложение для отказа от вредных привычек.
Во второй половине 2023 года, после множества доработок чужих приложений на фрилансе, связанных с улучшением здоровья и качества жизни, у меня появилась идея создать собственный счетчик отказа от вредных…
Во второй половине 2023 года, после множества доработок чужих приложений на фрилансе, связанных с улучшением здоровья и качества жизни, у меня появилась идея создать собственный счетчик отказа от вредных…
❤9👍6🔥4🙏1 1
Мобильный трудоголик pinned «💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни! Чтобы принять участие, нужно: 🔹 Подписаться на канал. 🔹 Нажать кнопку «Участвую!».»
Привет! Сегодня поговорим об архитектурных основах Swift, которые формируют фундамент работы с данными в наших приложениях. Речь пойдет о протоколах Sequence и Collection, тех строительных блоках, которые мы используем ежедневно, но чьи глубинные механизмы часто остаются за пределами нашего внимания.
В современной Swift-разработке понимание этих протоколов перестает быть опциональным знанием. Сложность приложений растет, требования к производительности ужесточаются, и умение выбирать правильные абстракции для работы с данными становится критически важным навыком.
Sequence:
Sequence представляет собой базовую концепцию последовательности элементов. Его философия проста: объект должен уметь предоставлять элементы один за другим, без обязательств по сохранению состояния или возможности повторного прохода.
Когда мы говорим о Sequence, мы имеем в виду контракт: «я могу дать вам итератор, который будет возвращать элементы до тех пор, пока они не закончатся». Именно эта простота делает Sequence идеальным для:
Collection:
Collection - это эволюция Sequence, добавляющая строгие гарантии и дополнительные возможности. Если Sequence - это поток, то Collection - это структурированное хранилище. Ключевые преимущества Collection включают:
Механика итерации:
То, что выглядит как простой синтаксический сахар:
for element in collection {
// обработка элемента
}
На самом деле преобразуется в полноценный механизм итерации:
var iterator = collection.makeIterator()
while let element = iterator.next() {
// обработка элемента
}
Такой подход обеспечивает несколько важных преимуществ:
Асинхронная революция: AsyncSequence
С приходом Swift Concurrency модель итерации получила развитие в виде AsyncSequence. Этот протокол расширяет знакомые концепции для работы с асинхронными потоками данных:
for try await event in eventStream {
await processEvent(event)
}
AsyncSequence становится особенно важен в контексте:
Рекомендации:
Когда выбирать Sequence:
Когда выбирать Collection:
Производительность:
Глубокое понимание иерархии протоколов позволяет писать более эффективный код. Компилятор Swift использует знания о соответствии типов этим протоколам для применения агрессивных оптимизаций:
Sequence и Collection - это фундаментальные подходы к работе с данными в Swift. Понимание их различий позволяет выбирать оптимальные решения для конкретных задач, предвидеть проблемы производительности и создавать эффективные кастомные реализации.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет! Сегодня поговорим о протоколе ~Copyable. Данный протокол позволяет запретить неявное копирование структур, что особенно полезно при работе с ресурсами вроде файлов или сетевых соединений.
Проблема, которую решает ~Copyable:
Представьте, что у вас есть структура для работы с файлом:
struct FileHandler: ~Copyable {
private var fileDenoscriptor: Int32
init(path: String) {
fileDenoscriptor = open(path, O_RDWR)
}
consuming func close() {
close(fileDenoscriptor)
}
}
// Временный доступ для чтения
func readFromFile(_ handler: borrowing FileHandler) {
let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 1024, alignment: 1)
defer { buffer.deallocate() }
let bytesRead = read(handler.fileDenoscriptor, buffer.baseAddress, 1024)
if bytesRead > 0 {
print("Прочитано \(bytesRead) байт")
}
}
// Передача владения
func takeOwnership(of handler: consuming FileHandler) {
print("Закрываем файл с дескриптором \(handler.fileDenoscriptor)")
handler.close()
}
// Изменение без передачи владения
func modifyFile(_ handler: inout FileHandler) {
let data = "Новые данные".data(using: .utf8)!
_ = data.withUnsafeBytes { buffer in
write(handler.fileDenoscriptor, buffer.baseAddress, buffer.count)
}
print("Данные записаны в файл")
}
let file = FileHandler(path: "data.txt")
readFromFile(file) // borrowing: file остается доступен
modifyFile(&file) // inout: изменяем, но владение не передается
takeOwnership(of: file) // consuming: передача владения, file больше не доступен
// file.close() // Ошибка компиляции! file уже недоступен
Без ~Copyable можно случайно создать копию структуры и получить две независимые переменные, работающие с одним файловым дескриптором. Это может привести к:
Как это работает:
После добавления ~Copyable компилятор начинает следить за перемещением экземпляров структуры. Теперь нужно явно указывать:
Когда это может быть полезно:
~Copyable особенно пригодится при:
~Copyable - это не просто очередная фича языка, а важный шаг к более безопасному и предсказуемому коду. Хотя подход требует некоторого переосмысления работы со структурами, результат стоит того: многие потенциальные ошибки переносятся из времени выполнения в время компиляции, что экономит часы отладки.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Apple продолжает радовать сообщество open-source инициативами, выпустив Swift Profile Recorder - мощный инструмент для профилирования производительности Swift-приложений. Давайте разберемся, что это за инструмент и как он может упростить жизнь разработчикам.
Что такое Swift Profile Recorder:
Это профилировщик, который работает прямо внутри вашего приложения. Ему не нужны дополнительные системные компоненты или специальные права доступа. Если говорить проще: теперь вы можете добавить профилирование в свои Swift-проекты, просто подключив библиотеку как зависимость.
Преимущества:
Практическое применение:
Добавление в проект занимает минимум усилий:
// Package.swift
dependencies: [
.package(url: "https://github.com/apple/swift-profile-recorder.git", from: "0.3.0")
]
// В коде приложения
import ProfileRecorderServer
@main
struct MyApp {
func run() async throws {
async let _ = ProfileRecorderServer(
configuration: .parseFromEnvironment()
).runIgnoringFailures(logger: logger)
// Основной код приложения
}
}
Сбор профиля через curl:
curl --unix-socket /tmp/app-samples-12345.sock \
-sd '{"numberOfSamples":1000,"timeInterval":"10ms"}' \
http://localhost/sample > profile.perf
Визуализация результатов:
Собранные данные можно анализировать в популярных инструментах:
Отличие от других решений:
В отличие от swift-parca, который использует eBPF и требует специальных привилегий, Swift Profile Recorder работает на уровне приложения. Это делает его идеальным для:
Swift Profile Recorder - это серьезный шаг в развитии инструментов для Swift-разработки. Он демократизирует доступ к продвинутому профилированию, делая его доступным для проектов любого масштаба.
Особенно ценно, что инструмент уже годами используется внутри Apple для отладки критически важных сервисов, что говорит о его надежности.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥11 5👀2✍1🙏1
Всем привет! Сегодня поговорим про библиотеку для работы с данными - SQLiteData, которая сочетает проверенную надежность SQLite с современным Swift-подходом. В основе библиотеки лежит идея предоставить разработчикам привычные инструменты, подобные тем, что есть в SwiftData, но с более предсказуемым поведением.
Модели данных:
Модели данных описываются с помощью структур и перечислений, что делает код интуитивно понятным и соответствующим духу Swift. Это обеспечивает:
Работа с запросами:
Для выборки данных предлагаются типобезопасные запросы, которые интегрируются в интерфейс через property wrappers. Важно, что эти обертки работают не только в SwiftUI, но и в любых
@Observable моделях, а также в контроллерах UIKit, что обеспечивает универсальность подхода.Интеграция с CloudKit:
Библиотека включает прямой доступ к возможностям CloudKit, обеспечивая:
Это избавляет от необходимости самостоятельной интеграции сторонних решений.
Технологическая основа:
В качестве основы используется SQLite через драйвер GRDB, что гарантирует высокую производительность и отказоустойчивость. Такой выбор технологии означает полный контроль над схемой данных и процессами миграции.
Пример:
// Модель
@Table
struct Task: Identifiable {
let id: UUID
var noscript: String
var isCompleted: Bool
}
struct TasksView: View {
// Запрос
@FetchAll(Task.where { !$0.isCompleted })
var pendingTasks
var body: some View {
List(pendingTasks) { task in
Text(task.noscript)
}
}
}
SQLiteData позиционируется как готовое решение для проектов, где важны стабильность, прозрачность работы с данными и современный подход к их обработке. Библиотека предлагает оптимальное сочетание надежности SQLite и современных Swift-практик.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17 9🔥4❤2🤔1
Привет! Хочу порекомендовать канал практикующего staff инженера из Т-Банка.
Обзоры самых актуальных новостей из мира iOS разработки, обзоры нововведений в Swift Evolution, розыгрыши билетов на конференции и просто советы для разработчиков.
➡️ Подписывайтесь на @ios_broadcast
Обзоры самых актуальных новостей из мира iOS разработки, обзоры нововведений в Swift Evolution, розыгрыши билетов на конференции и просто советы для разработчиков.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4🗿4❤1
В SwiftUI есть мощнейший инструмент для работы с графикой - Canvas API. Этот инструмент кардинально меняет подход к созданию сложных визуальных эффектов и кастомной графики в приложениях.
Проблемы до Canvas:
До появления Canvas разработчики сталкивались с серьезными ограничениями:
Фактически, для любой нетривиальной графики приходилось покидать комфортную декларативную среду SwiftUI.
Что такое Canvas API:
Canvas - это View в SwiftUI, предоставляющая прямой доступ к низкоуровневому рендерингу:
Canvas { context, size in
// Рисуем эллипс
context.fill(
Path(ellipseIn: CGRect(origin: .zero, size: size)),
with: .color(.blue)
)
// Добавляем текст
context.draw(Text("Hello Canvas"), at: CGPoint(x: size.width/2, y: size.height/2))
}Ключевые возможности:
🔹 GraphicsContext: сердце Canvas, предоставляет:
🔹 Производительность: Canvas работает напрямую с GPU, обеспечивая 60 FPS даже при сложных вычислениях.
🔹 Интеграция с SwiftUI: полная совместимость с анимациями, жестами и системой layout.
Ограничения:
Canvas API - это не просто рядовая фича в SwiftUI, а фундаментальное расширение возможностей фреймворка. Разработчики могут создавать сложную графику и визуальные эффекты, не покидая декларативной парадигмы.
Для проектов, где важна визуальная составляющая: анимированные onboarding-экраны, кастомные графики, интерактивные элементы - Canvas становится обязательным инструментом в арсенале разработчика.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Привет! У каждого из нас есть свои маленькие ритуалы. У кого-то это кофе определенным способом перед началом дня, у кого-то счастливая кружка, а у разработчиков это целый свод неписаных правил, которые, кажется, помогают коду работать.
У меня на столе, например, стоит собранный кубик Рубика и несколько сувениров, купленных в разных странах на удачу. Это не талисманы, конечно, но как-то спокойнее, когда они рядом.
Самые распространенные суеверия в нашей сфере:
Табу на пятничный деплой.
Это не суеверие, а правило выживания. Кто хоть раз разбирал последствия неудачного деплоя в пятницу вечером, тот понимает насколько неприятно исправлять проблемы в выходные, вместо отдыха. Это не суеверие, а скорее горький опыт, возведенный в традицию.
Феномен «озарения у доски».
Не можешь найти ошибку? Начни объяснять ее коллеге или просто проговори вслух и решение придет само. Именно из этого ритуала пошел мем с резиновым утенком. Выглядит со стороны очень забавно, но работает!
Проклятие «легкой задачи».
Стоит только сказать на планировании: «Да это за час сделается!», как задача обязательно превратится в многодневный марафон с переписыванием половины кодовой базы. Закон подлости? Или просто недооценка сложности?
Магический перезапуск.
Не работает? Не читай логи, а просто перезапусти! Не собирается? Перезапусти билд! И ведь часто это помогает!
«Не смотри на процесс сборки - упадет!» или «Смотри пристально, иначе сломается!».
Здесь разработчики делятся на два лагеря. Одни уверены: если ты уйдешь от монитора, пока идет билд, все обязательно сломается. Другие ровно наоборот: стоит только начать пристально следить за консолью, как система тут же выдаст ошибку. Парадокс! Каждому свое.
Почему это работает (или кажется, что работает)?
На самом деле, многие ритуалы - это способ вернуть себе ощущение контроля над сложными и непредсказуемыми системами. Психологи называют это «иллюзией контроля».
Когда мы выполняем ритуальные действия (не смотрим на процесс сборки, перезапускаем без чтения логов пайплайн), мы снижаем тревожность. А спокойный разработчик - это эффективный разработчик.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14 8👍4🔥1🫡1
Чтобы принять участие, нужно:
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Мобильный трудоголик
🍏 🏋️ Мое приложение для рассылки постов в социальных сетях — Social Poster.
В далеком 2018 году я решил разработать приложение Social Poster (SP) для автоматизации публикации объявлений по продаже б/у смартфонов в ВК группах (барахолках) и чатах объявлений…
В далеком 2018 году я решил разработать приложение Social Poster (SP) для автоматизации публикации объявлений по продаже б/у смартфонов в ВК группах (барахолках) и чатах объявлений…
👍8❤6🔥3 1
Мобильный трудоголик pinned «🛫 Дарим три подписки на полгода в приложении Social Poster - автопостинг по социальным сетям. Чтобы принять участие, нужно: 🔹 Подписаться на канал. 🔹 Нажать кнопку «Участвую!».»
Swift 6.2 принес долгожданную фичу - Raw Identifiers, которая ломает привычные ограничения именования переменных, функций и констант. Теперь мы можем использовать символы, которые раньше были под запретом.
До Swift 6.2 названия не могли:
Теперь достаточно заключить такое название в обратные кавычки (`), и ограничения снимаются!
Пример:
Вместо громоздких конструкций с аннотациями:
@Test("Пользователь нажимает кнопку сохранения без заполненных полей")
func testSaveButtonTapWithEmptyFields() {
}
Можно писать лаконично и понятно:
@Test
func `пользователь нажимает кнопку сохранения без заполненных полей`() {
}
Раньше для числовых значений приходилось искать обходные пути:
enum VideoFormat {
case resolution1080p
case resolution4K
case frameRate24
case frameRate60
}
Теперь называем вещи своими именами:
enum VideoFormat {
case `1080p`
case `4K`
case `24fps`
case `60fps`
}
Использование становится интуитивно понятным:
let format: VideoFormat = .`4K`
let frameRate: VideoFormat = .`60fps`
Важные нюансы:
Raw Identifiers - это не просто синтаксический сахар, а мощный инструмент для улучшения читаемости кода. Особенно полезно в тестировании и работе с внешними API, где точность формулировок критически важна.
Главное использовать новую возможность с умом, сохраняя баланс между выразительностью и практичностью.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет! Многие из нас столкнулись с неприятным сюрпризом при обновлении до Swift 6 и новее: старый добрый код внезапно перестал компилироваться. Жесткие проверки конкуренции выявляют проблемы там, где раньше все работало. Особенно болезненно это проявляется при работе с легаси-API от Apple, которые еще не адаптированы под новые требования.
В чем именно проблема:
Возьмем классический пример: создание UIHostingController внутри методов, которые не помечены как
@MainActor. Swift 6 видит потенциальную гонку данных и отказывается компилировать такой код:
class CustomAttachmentViewProvider: NSTextAttachmentViewProvider {
override func loadView() {
// Ошибка компиляции в Swift 6 и новее
let hosting = UIHostingController(rootView: MySwiftUIView())
self.view = hosting.view
}
}
Обычные решения не работают:
Многие пытаются решить проблему стандартными способами:
@MainActor к классу или методу@MainActor in }Но эти подходы либо не решают проблему полностью, либо создают новые сложности с передачей данных между контекстами.
Решение: MainActor.assumeIsolated:
Именно здесь на помощь приходит MainActor.assumeIsolated - метод, созданный специально для таких случаев:
class CustomAttachmentViewProvider: NSTextAttachmentViewProvider {
override func loadView() {
let view = MainActor.assumeIsolated {
let hosting = UIHostingController(rootView: MySwiftUIView())
hosting.view.backgroundColor = .clear
return hosting.view
}
self.view = view
}
}
Особенности работы метода:
Важные замечания:
Подробный пример использования:
class CustomAttachmentViewProvider: NSTextAttachmentViewProvider {
override func loadView() {
view = createViewSafely()
}
private func createViewSafely() -> UIView {
if Thread.isMainThread {
return Self.createHostingView()
} else {
return DispatchQueue.main.sync {
Self.createHostingView()
}
}
}
private static func createHostingView() -> UIView {
MainActor.assumeIsolated {
let hosting = UIHostingController(rootView: MySwiftUIView())
return hosting.view
}
}
}
MainActor.assumeIsolated - это не хаки и не костыли, а официально одобренный Apple способ решать проблемы совместимости в переходный период. Он позволяет сохранить работоспособность старого кода соблюдая строгие правила Swift 6.
Главное - использовать этот инструмент осознанно: проверять выполнение на главном потоке, тестировать краевые случаи и постепенно мигрировать на полностью безопасные подходы. Временные решения должны оставаться временными, даже если они очень эффективны.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍11 5🤯2🙏1👀1
Привет! С выходом iPadOS 26 работа с системным меню-баром вышла на совершенно новый уровень. Теперь iPad получил полноценное меню в стиле macOS с разделами File, Edit, View и другими, но что еще важнее: Apple наконец-то дала разработчикам полноценный инструментарий для тонкой настройки этого меню. Давайте разберемся, какие возможности открываются и как это изменит подход к разработке интерфейсов.
От хаков к нативным решениям:
Раньше кастомизация системного меню требовала нестандартных решений и обходных путей. Теперь в iPadOS 26 появился UIMainMenuSystem - специализированный подкласс UIMenuSystem, предназначенный именно для работы с главным меню-баром. Доступ к нему осуществляется через синглтон:
let configuration = UIMainMenuSystem.Configuration()
UIMainMenuSystem.shared.setBuildConfiguration(configuration) { menuBuilder in
// Ваша логика кастомизации
menuBuilder.remove(menu: .file)
}
Точечный контроль над структурой меню:
Ключевое нововведение - возможность модифицировать меню динамически, без необходимости пересобирать всю структуру целиком. Новые методы UIMenuBuilder позволяют:
Упрощенная настройка через Configuration:
Отдельного внимания заслуживает UIMainMenuSystem.Configuration - класс, который группирует свойства для быстрой настройки основных групп меню:
let configuration = UIMainMenuSystem.Configuration()
configuration.newScenePreference = .removed
configuration.findingConfiguration.style = .search
Это изящная альтернатива ручному удалению элементов через buildHandler.
Гибкая настройка поиска:
Особенно полезным оказалось findingConfiguration. В зависимости от типа приложения можно выбрать один из четырех стилей:
Практические сценарии применения:
Новые возможности особенно полезны для:
Эти обновления знаменуют важный этап в развитии iPadOS, платформа становится еще ближе к macOS, предоставляя разработчикам инструменты для создания понастоящему профессиональных интерфейсов. Это особенно важно для сложных приложений, где контекстно-зависимое меню напрямую влияет на пользовательский опыт.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет! Одна из самых критичных задач в iOS-разработке: изменение структуры базы данных без потери пользовательских данных. Представьте: вы выпускаете обновление приложения, а у пользователей пропадают все сохраненные данные. Это катастрофа! К счастью, Core Data предлагает элегантное решение: легкую миграцию. Сейчас разберем, как это работает.
Что такое легкая миграция и когда она возможна:
Легкая миграция - это автоматический процесс, при котором Core Data самостоятельно определяет различия между старой и новой версией модели данных и применяет необходимые преобразования.
Что не поддерживается в легкой миграции:
Использование легкой миграции:
Для успешного автоматического обновления модели данных необходимо выполнить три последовательных действия:
Рассмотрим каждый этап подробно:
Активация механизма миграции:
При использовании современного подхода с NSPersistentContainer дополнительная настройка не требуется, система автоматически включает поддержку легких миграций.
Если же вы работаете с собственной реализацией стека Core Data, потребуется явно указать необходимые опции при подключении хранилища:
let persistentStoreCoordinator = NSPersistentStoreCoordinator(
managedObjectModel: dataModel
)
let migrationOptions: [AnyHashable: Any] = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true
]
do {
try persistentStoreCoordinator.addPersistentStore(
ofType: NSSQLiteStoreType,
configurationName: nil,
at: databaseURL,
options: migrationOptions
)
} catch {
// Обработка неудачной миграции
}
Эти два параметра дают Core Data команду: автоматически определять различия между схемами данных и выполнять преобразования, когда это возможно.
Создание новой версии модели:
Для корректной миграции системе необходимо видеть как исходную, так и целевую версию модели данных.
Важное правило: никогда не редактируйте непосредственно существующий файл .xcdatamodeld после публикации приложения. Вместо этого:
Теперь можно безопасно вносить изменения, не затрагивая структуру, с которой работают пользователи текущей версии приложения.
Редактирование обновленной модели:
Вносите изменения исключительно в новую, только что созданную версию модели. Core Data сможет автоматически построить карту преобразований, если изменения соответствуют определенным шаблонам:
Проверка возможности автоматической миграции:
let canMigrateAutomatically = try? NSMappingModel.inferredMappingModel(
forSourceModel: previousModelVersion,
destinationModel: updatedModelVersion
) != nil
if canMigrateAutomatically {
// Легкая миграция возможна
} else {
// Требуется ручная (тяжелая) миграция
}
Если метод возвращает nil, это означает, что Core Data не может самостоятельно сопоставить версии моделей.
Легкая миграция Core Data - мощный инструмент, который избавляет разработчиков от ручного написания сложных скриптов миграции. При правильном использовании (создание новых версий модели, а не изменение существующих) система надежно перенесет данные пользователей между версиями приложения.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет! Мобильная экосистема стоит на пороге важных изменений. Apple недавно внесла существенные правки в App Review Guidelines, которые кардинально меняют правила игры для разработчиков. Речь идет не просто о технических требованиях, а о фундаментальном принципе: оригинальность против плагиата.
Контекст проблемы: эпидемия клонов.
Вспомните ситуацию с релизом Sora 2 от OpenAI. Через несколько дней после официального запуска App Store заполонили десятки клонов с похожими названиями, иконками и описаниями. Пользователи путались, разработчики оригинального приложения теряли аудиторию, а экосистема деградировала.
Что именно изменилось в правилах:
Нововведения фокусируются на трех ключевых аспектах:
Технические детали обновлений:
Помимо антиплагиатных правил, Apple внесла и другие важные изменения:
Как подготовиться к новым правилам:
Эти изменения - не просто бюрократические правки. Это сигнал о зрелости мобильной экосистемы. Apple признает, что для здорового развития рынка нужны не сотни похожих приложений, а разнообразие уникальных идей.
Для разработчиков это означает переход от тактики «быстрого клонирования» к стратегии «устойчивой оригинальности». В долгосрочной перспективе это выгодно всем: пользователи получают качественные уникальные продукты, а разработчики - справедливые условия конкуренции.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17👀10🤯5🔥2 2