[Widgets]: Enhanced to isolate operations from multiple views of same widget type

This commit is contained in:
Magesh K
2025-01-11 03:25:25 +05:30
parent f69b293004
commit e29d9f7904
12 changed files with 346 additions and 245 deletions

View File

@@ -7,49 +7,50 @@
//
import AppIntents
import Intents
import WidgetKit
public enum Direction: String, Sendable{
case up = "up"
case down = "down"
case up
case down
}
public struct NavigationEvent {
let direction: Direction?
var consumed: Bool = false
}
@available(iOS 17, *)
final class PaginationIntent: AppIntent, @unchecked Sendable {
class PaginationIntent: AppIntent, @unchecked Sendable {
static var title: LocalizedStringResource { "Page Navigation Intent" }
static var isDiscoverable: Bool { false }
private let COMMON_WIDGET_ID = 1
static var title: LocalizedStringResource = "Page Navigation Intent"
static var isDiscoverable: Bool = false
@Parameter(title: "widgetID")
var widgetID: Int
@Parameter(title: "Direction")
var direction: String
@Parameter(title: "WidgetID")
var widgetID: String
required init(){}
var uuid: String = UUID().uuidString
required init(){
print()
}
init(_ direction: Direction, _ widgetID: String){
init(_ widgetID: Int?, _ direction: Direction){
// if id was not passed in, then we assume the widget isn't customized yet
// hence we use the common ID, if this is not present in registry of PageInfoManager
// then it will return nil, triggering to show first page in the provider
self.widgetID = widgetID ?? COMMON_WIDGET_ID
self.direction = direction.rawValue
self.widgetID = widgetID
}
func perform() async throws -> some IntentResult {
// if let widgetID = self.widgetID
// {
// WidgetCenter.shared.reloadTimelines(ofKind: widgetID)
// }
// return .result()
let result = try await WidgetUpdateIntent(
Direction(rawValue: self.direction),
self.widgetID
).perform()
return result
let widgetIdString = String(widgetID)
DispatchQueue(label: widgetIdString).sync {
let navigationEvent = NavigationEvent(direction: Direction(rawValue: direction))
PageInfoManager.shared.setPageInfo(for: widgetID, value: navigationEvent)
WidgetCenter.shared.reloadTimelines(ofKind: widgetIdString)
}
return .result()
}
}

View File

@@ -11,32 +11,9 @@ import AppIntents
@available(iOS 17, *)
final class WidgetUpdateIntent: WidgetConfigurationIntent, @unchecked Sendable {
static var title: LocalizedStringResource { "Intent for WidgetAppIntentConfiguration receiver type" }
static var title: LocalizedStringResource { "Widget ID update Intent" }
static var isDiscoverable: Bool { false }
var uuid: String = UUID().uuidString
private var widgetID: String?
@Parameter(title: "ID", description: "Change this to unique ID to keep changes isolated from other widgets", default: "1")
var ID: String?
// this static hack is required, coz we are making these intents stateful
private static var directionMap: [String: Direction] = [:]
init(){
print()
}
func getDirection( _ widgetID: String) -> Direction? {
// remove it, since the event is processed. if needed it will be added again
return Self.directionMap.removeValue(forKey: widgetID)
}
init(_ direction: Direction?, _ widgetID: String){
Self.directionMap[widgetID] = direction
}
func perform() async throws -> some IntentResult {
return .result()
}
@Parameter(title: "ID", description: "Provide a numeric ID to identify the widget", default: 1)
var ID: Int?
}