SwiftUI Bindings Сейчас немного загружен задачами, поэтому обещанный пост про детали работы @resultBuilder будет на следующей неделе. А пока хочется поговорить про работу с Binding в SwiftUI. Думаю, многие читали статью Chris Eidhof Not all Bindings are created equal. В ней автор рассказывает о том, что Binding(get:set:) — достаточно опасная вещь, потому что вызывает постоянные инвалидации View.body. struct ContentView: View { @State var value1 = false @State var value2 = false var body: some Vi...
Fckn Coding (Swift Notes)
Делюсь опытом в iOS-разработке. В канале полезные статьи, доклады и другие материалы 🐣 По всем вопросам: @kn1kt
Графики
📊 Средний охват постов
📉 ERR % по дням
📋 Публикации по дням
📎 Типы контента
Лучшие публикации
20 из 20DynamicMemberLookup Недавно я занимался конфигурациями сборки в Tuist и заметил, как прикольно у них сделана работа с окружением. Все переменные окружения, соответствующие шаблону TUIST_XXX, будут доступны как обычные свойства в Environment: // TUIST_APP_NAME Environment.appName.getString(default: "TuistServer") // TUIST_STATIC_LINKING Environment.staticLinking.getBoolean(default: false) Если вам, как и мне, сразу стало интересно, как можно связать динамические значения из окружения и обращения ...
Swift Concurrency Guide pt3: Internals И в конце несколько полезных ссылок для тех, кому интересно как все это работает под капотом. Подробный разбор от самих Apple: 🟣Swift concurrency: Behind the scenes А здесь уже более глубокое погружение в компилятор, а так же пост с апдейтами, которые успели произойти: 🟣How async/await works internally in Swift 🟣SerialExecutor
Окей, бойлерплейта не осталось. Но ко всем проблемам прошлого решения добавились проблемы стилей. Теперь их никак не получится переопределить или как-то кастомизировать: MyLabel { MyTitle("Title") .font(.title) // Will be ignored. MySubtitle("Subtitle") .mySubtitleStyle(.customStyle) // Will be ignored. } icon: { / ... / } А еще нужно следить, чтобы эти стили случайно не переопределили стили других вложенных компонентов. После двух неудачных подходов начинает складываться понимание, что в ...
Swift Concurrency Guide pt2: Advanced Для того, чтобы погрузиться в оставшиеся ключевые концепты SC, рекомендую прочитать достаточно короткий, но при этом очень емкий гайд: 🔵Fucking Approachable Swift Concurrency Еще в нем есть ссылка на skill для ваших агентов: 🔵Swift Concurrency Agent Skill Детальное объяснение различий между Structured и Unstructured Concurrency от Apple: 🔵Beyond the basics of structured concurrency Debug Еще одно обучающее видео от Apple про профилирование SC: 🔵Visualize...
Что ещё можно сделать, чтобы улучшить это решение? В большинстве ресурсов и даже в документации Apple, можно найти примеры в духе: @resultBuilder struct ExampleResultBuilder { // ... static func buildBlock(_ components: Component...) -> Component { ... } Они, к сожалению, не подскажут верное решение. Но если заглянуть в исходники SwiftUI, то можно заметить, что ViewBuilder выглядит по-другому: @resultBuilder struct ViewBuilder { // ... static func buildBlock<each Content: View>( _ content: repea...
SwiftUI Bindings 2 Не могу завершить эту тему, не рассказав про еще один лайфхак, связанный с работой Bindings. Вторая популярная ситуация, когда хочется использовать Binding(get:set:), — это случаи, когда ваш стейт нельзя мутировать напрямую. Такое ограничение может быть вызвано разными причинами, например, сложной логикой управления этим стейтом или необходимостью выполнения сайд-эффектов. Для лучшего понимания рассмотрим такой простой пример: @Observable final class DetentsHolder { private(se...
Самый непонятный и редко используемый метод — это: /// Enables support for..in loops in a result builder by combining the results of all iterations into a single result. static func buildArray(_ components: [Component]) -> Component { ... } Почему непонятный? До Swift 5.8 он работал ожидаемо, но затем его функционал сильно порезали, и теперь кроме ошибки: "Underlying type for opaque result type 'some Type' could not be inferred from return expression" он почти ничего не выдает. Виной всему гомог...
Swift Concurrency Guide Новый год — время для чего-то нового. Для SwiftUI план изучения в канале уже есть, поэтому решил сделать еще один, но уже по Swift Concurrency (SC). Как обычно, начнем с самого просто, а затем двинемся к более сложным концептам. Essentials Начать рекомендую с обучающих видео от Apple, потому что они достаточно просто объясняют основные концепции и подсвечивают ключевые моменты, необходимые для дальнейшей работы. Погружаемся в то, что такое async функции и actor'ов: 🟢Meet...
Custom View Builders Думаю, многим из вас приходилось писать SwiftUI контейнеры, которые должны отображать список определённых View. Например, список из нескольких кнопок: struct ButtonsList: View { let models: [ButtonModel] var body: some View { VStack { ForEach(models, id: \.title) { model in Button(action: model.action) { Text(model.title) } .buttonStyle(.borderedProminent) } } } } struct ButtonModel { let title: String let action: @MainActor () -> Void } Однако в таком случае использова...