Search code examples
iosswiftwidgetkit

WidgetKit - Is there a way to section the data in intent handling during edit widget


This is how we provide "edit widget" feature in WidgetKit, by using an intent definition file.

Intent definition file

enter image description here

Outcome during Edit widget

enter image description here


To provide a list of selection, during intent handling (When the edit widget page is tap), this is our code.

import Intents

class IntentHandler: INExtension, ConfigurationIntentHandling {
    
    func provideWidgetItemOptionsCollection(for intent: ConfigurationIntent, with completion: @escaping (INObjectCollection<WidgetItem>?, Error?) -> Swift.Void) {
        var widgetItems = [WidgetItem]()
        
        widgetItems.append(WidgetItem(identifier: "1", display: "Visit grandma"))
        widgetItems.append(WidgetItem(identifier: "2", display: "Don't forget milk"))
        widgetItems.append(WidgetItem(identifier: "3", display: "Buy socks"))
        widgetItems.append(WidgetItem(identifier: "4", display: "Pick up laundry"))
        widgetItems.append(WidgetItem(identifier: "5", display: "Reply email"))
        widgetItems.append(WidgetItem(identifier: "6", display: "Meeting at 3pm"))
        
        let collection = INObjectCollection(items: widgetItems)
        
        completion(collection, nil)
    }
    
    override func handler(for intent: INIntent) -> Any {
        // This is the default implementation.  If you want different objects to handle different intents,
        // you can override this and return the handler you want for that particular intent.
        
        return self
    }
    
}

and this is the outcome

Outcome during Intent handling

enter image description here

I was wondering, is there a way to create multiple section on the UI?

For instance,

[Personal]
"Visit grandma"
"Don't forget milk"
"Buy socks"
"Pick up laundry"

[Work]
"Reply email"
"Meeting at 3pm"

Thanks.


Solution

  • Here's the solution.

    import Intents
    
    class IntentHandler: INExtension, ConfigurationIntentHandling {
        
        func provideWidgetItemOptionsCollection(for intent: ConfigurationIntent, with completion: @escaping (INObjectCollection<WidgetItem>?, Error?) -> Swift.Void) {
            
            var personalWidgetItems = [WidgetItem]()
            var workWidgetItems = [WidgetItem]()
            
            personalWidgetItems.append(WidgetItem(identifier: "1", display: "Visit grandma"))
            personalWidgetItems.append(WidgetItem(identifier: "2", display: "Don't forget milk"))
            personalWidgetItems.append(WidgetItem(identifier: "3", display: "Buy socks"))
            personalWidgetItems.append(WidgetItem(identifier: "4", display: "Pick up laundry"))
            workWidgetItems.append(WidgetItem(identifier: "5", display: "Reply email"))
            workWidgetItems.append(WidgetItem(identifier: "6", display: "Meeting at 3pm"))
            
            let personalSection = INObjectSection(title: "Personal", items: personalWidgetItems)
            let workSection = INObjectSection(title: "Work", items: workWidgetItems)
            
            let collection = INObjectCollection(sections: [personalSection, workSection])
            
            completion(collection, nil)
        }
        
        override func handler(for intent: INIntent) -> Any {
            // This is the default implementation.  If you want different objects to handle different intents,
            // you can override this and return the handler you want for that particular intent.
            
            return self
        }
        
    }
    

    , and here's the outcome.

    enter image description here