Pull to refresh
5
0
Антон Тимонин@antonidas37

ios dev

Send message

А будет ли сравнение с Proxyman?
Интересно было бы почитать :)

Не наблюдали проблем с передачей данных через UserDefaults. А в чём проблема конкретна была?
Интересно узнать кейс проблемы и её решения ?

Можно сделать, как property wrapper. Кому как нравится)
Мне показался странным синтаксис инициализации переменной с нижним подчёркиванием, обёрнутой property wrapper, поэтому сделал через обычный generic

class SomeClass {
    
    @UserDefaultCodable var someVar: Int
    
    init(key: String) {
        self._someVar = .init(key: key, defaultValue: 0)
    }
}

Добавил ли эпл для нас возможность как-то отлавливать нажатия кнопки/свича, чтобы мы понимали, когда произошло нажатие для обновления ui?

— Отлавливать нажатия в виджете во View в привычном смысле нельзя. Потому что каждое нажатие на Button/Toggle триггерит перерисовку всей вьюхи: в терминах виджета, один снепшот с данными перерисовывается на другой. Поэтому завязаться на булеву переменную и при нажатии на Toggle менять состояние не получится

Но Apple добавила другой способ, через который можно обработать этот случай, через задание стилей для Button/Toggle: ButtonStyle и ToggleStyle аналогично. Необходимо дописать свой стиль

На примере Toggle:

// Описываем кастомный стиль для Toggle
struct CheckToggleStyle: ToggleStyle {
    
    var onToggleImage: (Bool) -> Image
    var imageColor: Color
    
    init(imageColor: Color,
         _ onToggleImage: @escaping (Bool) -> Image) {
        self.onToggleImage = onToggleImage
        self.imageColor = imageColor
    }
    
    func makeBody(configuration: Configuration) -> some View {
        Button {
            configuration.isOn.toggle()
        } label: {
            Label {
                self.onToggleImage(configuration.isOn)
                    .resizable()
                    .renderingMode(.template)
                    .foregroundColor(self.imageColor)
            } icon: { }
        }
        .buttonStyle(.plain)
    }
}

Создаём Toggle во вью. Из-за особенностей работы с виджетом, делаем с захардкоженными данными. Это позволительно, так как после нажатия на Toggle, его состояние будет всё равно меняться.

Toggle("",
       isOn: false,
       intent: SwipeAppIntent())
  .toggleStyle(CheckToggleStyle(imageColor: .softYellow) { isOn in
      Image(uiImage: (isOn ? .starFilledIcon : .starUnfilledIcon) ?? UIImage())
    })
  .frame(width: 30.0, height: 30.0)

И для красоты, устанавливаем задержку в 0.3 секунды в AppIntent

struct SwipeAppIntent: AppIntent {
    
    static var title: LocalizedStringResource = "Swipe card"
    static var isDiscoverable: Bool = false
    
    func perform() async throws -> some IntentResult {
        // Спим 0.3 секунды
        try await Task.sleep(nanoseconds: 300_000_000)

        // Продолжаем работу
        let key = "group.Revolvetra.Inc.Ficha"
        let storage: WordsStorageProtocol = WordsStorage(key: key)
        storage.swipeCard()
        return .result()
    }
}

Toggle кнопки избранное
Toggle кнопки избранное

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

— Такой случай, в предыдущем решении вряд ли можно обработать. Есть единственный вариант, в случае ошибки внутри метода perform в AppIntent выкинуть ошибку (throw Error), тк сигнатура метода позволяет это сделать func perform() async throws -> some IntentResult
В таком случае, виджет перезагрузится, но так как данные не поменялись, то вью моргнёт

Information

Rating
Does not participate
Registered
Activity

Specialization

Бэкенд разработчик, Разработчик мобильных приложений
Git
Swift
Golang
SwiftUI
PostgreSQL
Ruby
Grafana