swift – WidgetKit iOS 17 : Interactive widget no longer responsive after a long idle time


I have developed an interactive widget which looks as the following

enter image description here

It is using CoreData.

The view is implemented as the following

struct widget_extensionEntryView : View {
    var body: some View {
        if let nsTodoList = nsTodoList {
            VStack(alignment: .leading, spacing: 1) {
                ...
                ForEach(0..<prefixGoodNSTodoArray.count, id: \.self) { index in
                    ...
                    let todoIntent = TodoIntent(objectIDAsString: objectIDAsString, parentOrder: parentOrder)
                    
                    Button(intent: todoIntent) {
                    }
                }
            }
        }
    }
}

The AppIntent is implemented as the following

import Foundation
import AppIntents
import WidgetKit
import CoreData

struct TodoIntent: AppIntent {
    static var title: LocalizedStringResource = "Complete Task"
    static var description: IntentDescription = IntentDescription("Complete selected task")
    
    @Parameter(title: "objectIDAsString")
    var objectIDAsString: String
    
    @Parameter(title: "parentOrder")
    var parentOrder: Int
    
    init() { }
    
    init(objectIDAsString: String, parentOrder: Int) {
        self.objectIDAsString = objectIDAsString
        self.parentOrder = parentOrder
    }
    
    func perform() async throws -> some IntentResult {
        guard let objectID = NSManagedObjectID.from(objectIDAsString) else { return .result() }
        
        guard let nsTodoList = NSTodoListRepository.INSTANCE.getNSTodoList(objectID) else { return .result() }
        
        nsTodoList.toggleChecked(context: CoreDataStack.INSTANCE.viewContext, parentOrder: Int64(parentOrder))
        
        RepositoryUtils.saveContextIfPossible(CoreDataStack.INSTANCE.viewContext)
        
        TodoWidgetOptions.isWrittenByWidgetExtension = true
        
        // Refresh all home widgets.
        // TODO: https://developer.apple.com/forums/thread/721937
        WidgetCenter.shared.reloadAllTimelines()
        
        return .result()
    }
}

The interactive widget works pretty well.

However, tapping on the widget has no response in the following situations:

  1. After an overnight, we turn on the iPhone’s screen and tap on the widget.
  2. After a few hours of idle time, we turn on the iPhone’s screen and tap on the widget.

One of the steps below will make the widget workable again:

  1. Launch and close the main app again. The main app will call WidgetCenter.shared.reloadAllTimelines() during sceneDidEnterBackground.
  2. Press and hold on the widget, choose ‘Edit widget’, and select the desired Todo list.

One thing to take note of is that I am using IntentTimelineProvider instead of AppIntentTimelineProvider. The reason I am using ‘older tech’ is due to the limitation mentioned in In iOS 17 AppIntent, how we can perform dynamic data selection for Widget?.

However, I am not sure whether this is the root cause of the problem.

Does anyone have any idea why such a problem occurs?

Thanks.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img