Intro to iOS Development
  • Welcome
    • β˜€οΈIntroduction
    • 🐣Getting Started
    • 🐦Course Staff
  • Logistics
    • πŸ“œSyllabus
    • πŸ—“οΈSchedule
    • πŸ–ŠοΈGrading
    • πŸ™‹β€β™‚οΈOffice Hours
    • Ed Discussion
  • Assignments
    • 🍼A1: Swift Basics
    • πŸ§‘A2: Profile
    • πŸ’¬A3: ChatDev
    • πŸ‘¨β€πŸ³A4: ChefOS
    • πŸ‘¨β€πŸ³A4: ChefOS - SwiftUI
    • πŸ“±Hack Challenge
      • πŸ†FA23 Winners
  • Lectures
    • 1️⃣Logistics + Swift Basics
    • 2️⃣UIKit + AutoLayout
  • 3️⃣MVC + Navigation + Delegation
  • 4️⃣UITableView
  • 5️⃣UICollectionView
  • 6️⃣Networking I
  • 7️⃣Networking II
  • 8️⃣SwiftUI I
  • 9️⃣SwiftUI II
  • πŸ”ŸPersistence + SnapKit
  • πŸ””(11) Notifications
  • 🌎(12) Deployment and MapKit
  • Chapters
    • πŸ–οΈIntroduction
    • ☁️Git + GitHub
      • 1️⃣Git Installation
      • 2️⃣Git Basics
      • βž•Git+
    • 🐣Swift Basics
      • 1️⃣Variables and Constants
      • 2️⃣Data Types
      • 3️⃣Operators
      • 4️⃣Data Structures
      • 5️⃣Conditionals
      • 6️⃣Loops
      • 7️⃣Functions
      • 8️⃣Closures
      • 9️⃣Optionals
    • 🧰UIKit + AutoLayout
      • 1️⃣Classes
      • 2️⃣UIKit
      • 3️⃣AutoLayout
    • πŸ“ΊMVC + Navigation + Delegation
      • 1️⃣MVC
      • 2️⃣Navigation
      • 3️⃣Delegation
    • πŸ“UITableView
      • 1️⃣What is a UITableView?
      • 2️⃣UITableView Setup
    • πŸ“šUICollectionView
      • 1️⃣What is a UICollectionView?
      • 2️⃣UICollectionView Setup
    • 🌐Networking I
      • 1️⃣HTTP Requests
      • 2️⃣Callbacks
      • 3️⃣Codable
    • 🌍Networking II
      • 1️⃣Alamofire
      • 2️⃣GET Requests
      • 3️⃣POST Requests
      • 4️⃣URLSession
    • πŸ’ΎPersistence + SnapKit
      • 1️⃣Persistence
      • 2️⃣SnapKit
    • πŸ•ŠοΈSwiftUI
      • 1️⃣Introduction to SwiftUI
      • 2️⃣Getting Started with SwiftUI
      • 3️⃣Views + Modifiers
      • 4️⃣Layouts
      • 5️⃣Navigation
      • 6️⃣Property Wrappers
    • πŸŽ›οΈWidgets
      • 1️⃣Introduction to Widgets
      • 2️⃣Setting Up Widgets
      • 3️⃣Building Widgets
      • 4️⃣Configuring Widgets
    • 🧱Project Foundation
    • βœ…Testing
      • 1️⃣Unit Testing
    • πŸ‘£Debugging
      • 1️⃣OSLog
      • 2️⃣Crashlytics
      • 3️⃣Analytics
    • ☁️CI/CD
      • 1️⃣Xcode Cloud
      • 2️⃣AppStore Shipping
  • Guides
    • πŸ”¨Xcode Project Setup
    • 🎨Figma
    • πŸ“¬Postman
    • πŸ₯₯CocoaPods
    • 🧰UIKit Handbook
    • πŸ“‘Tab Views
      • UITabBarController
      • TabView
  • Work in progress
    • 🧡Concurrency
    • 2️⃣UI Testing
    • πŸ•Reactive Programming
    • 🧠Memory Management
      • πŸ”ARC
    • πŸ“¦Storage
    • πŸ“£Notifications
  • Archived
    • SP24
      • Logistics
        • πŸ“œSyllabus
        • πŸ—“οΈSchedule
        • πŸ–ŠοΈGrading
        • πŸ™‹β€β™‚οΈOffice Hours
      • Assignments
        • 🍼A1: Swift Basics
        • πŸ§‘A2: Profile
        • πŸ’¬A3: ChatDev
        • πŸ‘¨β€πŸ³A4: ChefOS
        • πŸ“±Hack Challenge
          • πŸ†FA23 Winners
      • Lecture
        • 0️⃣Course Intro + Logistics + Git Setup
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • πŸ”ŸSwiftUI
        • πŸ”’TabViews
    • FA23
      • Logistics
        • 🐣Getting Started
        • 🐦Course Staff
        • πŸ“œSyllabus
        • πŸ—“οΈSchedule
        • πŸ–ŠοΈGrading
        • πŸ™‹β€β™‚οΈOffice Hours
      • Assignments
        • 🍼A1: Swift Basics
        • πŸ§‘A2: Profile
        • πŸ’¬A3: ChatDev
        • πŸ‘¨β€πŸ³A4: ChefOS
        • πŸ“±Hack Challenge
          • πŸ†FA23 Winners
      • Lectures
        • 0️⃣Course Intro + Logistics
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • πŸŽ›οΈWidgets
          • πŸ‘ΌIntroduction to Widgets
          • βš’οΈSetting Up Widgets
          • 🧱Building Widgets
          • πŸ‘¨β€πŸ’»Configuring Widgets
        • πŸ”ŸSwiftUI
    • SP23
      • Logistics
        • Lecture Schedule
        • Syllabus
        • Grading
        • SP23 Office Hours
      • Chapters
        • 1. Intro to Swift & Xcode
          • Lecture Handout
          • Lecture Demo
          • 🍼Project: Swift Basics
        • 2. UIKit and AutoLayout
          • Lecture Handout
          • Lecture Demo
          • πŸ›’Project: UIKit + AutoLayout
        • 3. Navigation, MVC, and Delegation
          • Lecture Handout
          • Lecture Demo
          • Project: Navigation + Delegation
        • 4. UITableView
          • Lecture Handout
          • Lecture Demo
          • Project: UITableView
        • 5. UICollectionView
          • Lecture Handout
          • Lecture Demo
          • Project: UICollectionView
        • 6. Networking I
          • Lecture Handout
          • Lecture Demo
          • Project: Persistence
        • 7. Networking II
          • Lecture Handout
          • Lecture Demo
            • Message Board
          • Project: Networking II
        • 8. Swift UI
        • 9. CocoaPods
          • 🍫Lecture Handout
          • πŸ§‘β€πŸ³Lecture Demo
      • Cheat Sheets
        • Setting Up a New Xcode Project
        • Submitting Your Projects
        • Setting Up CocoaPods
    • 2022
      • SwiftUI
    • 2021
      • Adding Flare
      • Project: UIView Animations (Optional - Extra Credit)
      • UIView Animations
      • Xcode Tips and Tricks
    • 2019
      • Firebase
      • Persistence: UserDefaults
  • Swift Guide (ARCHIVED)
    • About this Textbook
    • Documentation
    • Constants and Variables
      • Variable Properties
      • Lazy and Static Variables
    • Functions
    • Ranges
    • Arrays
      • Basic Array Operations
      • Iteration and Enumeration
      • Advanced Array Operations
    • Tuples
    • Conditions and While Loops
    • For Loops
    • Enums and Switches
      • Enums with Associated Values
      • Indirect Enums
    • Classes and Structs
    • Optionals
    • Dictionaries
      • Dictionary Implementation
    • Closures
    • Constraints
    • Generics
    • Protocols
      • Protocols With Associated Types
    • Casting
    • Errors
    • Networking
      • Result
    • Inout
Powered by GitBook
On this page
  • AppIntents
  • Creating a New Intent
  • Changes to WeatherEntry
  • Changes to WeatherTimelineProvider
  • Changes to Widget Configuration
  • Changes to View

Was this helpful?

Export as PDF
  1. Archived
  2. FA23
  3. Lectures
  4. Widgets

Configuring Widgets

Original Author: Reade Plunkett

AppIntents

AppIntents is the framework developed by Apple that allows us to configure our widgets with custom information provided by the user.

Creating a New Intent

We will create a new intent that allows the user to input a location and have the weather widget update its displayed conditions.

Let’s start by creating a new Swift file, which we will call LocationAppIntent.

Within that file, we will define a new structure that conforms to the WidgetConfigurationIntent protocol. This protocol provides us with an interface for configuring a WidgetKit widget.

LocationAppIntent.swift
import WidgetKit
import AppIntents

struct LocationAppIntent: WidgetConfigurationIntent {

}

This protocol requires us to implement a title for this Intent. Additionally, we can also implement a description on what this intent does.

LocationAppIntent.swift
static var title: LocalizedStringResource = "Location"
static var description = IntentDescription("Enter a location to view the weather.")

Next, we can define a parameter for this intent with a default value. The parameter will contain the location that use inputs.

LocationAppIntent.swift
@Parameter(title: "Location", default: "Ithaca, NY")
var location: String

Changes to WeatherEntry

Since our intent can make changes to a widget entry within our timeline, we must include it inside of the WeatherEntry model.

WeatherWidgetEntry.swift
import WidgetKit

struct WeatherEntry: TimelineEntry {
    let date: Date
    let weather: Weather
    let configuration: LocationAppIntent
}

Changes to WeatherTimelineProvider

We must also update our timeline provider to support this new app intent. We will change our provider to conform to the AppIntentTimelineProvider protocol to do so.

WeatherWidgetProvider.swift
struct Provider: AppIntentTimelineProvider {

}

Additionally, we will need to update the function headers for fetching a snapshot and timeline entry.

WeatherWidgetProvider.swift
func snapshot(for configuration: LocationAppIntent, in context: Context) async -> WeatherEntry {

}
WeatherWidgetProvider.swift
func timeline(for configuration: LocationAppIntent, in context: Context) async -> Timeline<WeatherEntry> {

}

These two functions provide us with the intent called configuration that contain user-customized values for the location.

Within both of these functions, we have to update our WeatherEntry instantiation to pass in the configuration.

WeatherWidgetProvider.swift
let entry = WeatherEntry(date: Date(), weather: possibleWeathers.randomElement()!, configuration: configuration) 

Additionally, we also have to update the entry created within our placeholder function with a new intent object.

WeatherWidgetProvider.swift
func placeholder(in context: Context) -> WeatherEntry {
    return WeatherEntry(date: Date(), weather: .sunny, configuration: LocationAppIntent())
}

Changes to Widget Configuration

Within WeatherWidget.swift, we also have to change our widget’s configuration from StaticConfiguration to AppIntentConfiguration.

WeatherWidget.swift
AppIntentConfiguration(kind: kind, intent: LocationAppIntent.self, provider: Provider()) { entry in
    WeatherWidgetView(entry: entry)
}

Changes to View

Finally, within WeatherWidgetView, we can update the β€œIthaca, NY” string to display the location passed in through the app intent associated with the timeline entry being displayed.

WeatherWidgetView.swift
HStack {
    Text(entry.configuration.location)
        .font(.system(size: 18, weight: .semibold))
        .minimumScaleFactor(0.5)
    Spacer()
}

Additionally, to view the widget in the Preview window, we will need to provide it with a default configuration. We can define a default intent as an extension of our LocationAppIntent within our view. Since we do not want this default value being used anywhere outside this file, we mark it with fileprivate.

WeatherWidgetView.swift
extension LocationAppIntent {
    fileprivate static var cupertino: LocationAppIntent {
        let intent = LocationAppIntent()
        intent.location = "Cupertino, CA"
        return intent
    }
}

We then update the preview entries to use this new configuration.

WeatherWidgetView.swift
#Preview(as: .systemSmall) {
    WeatherWidget()
} timeline: {
    WeatherEntry(date: .now, weather: .sunny, configuration: .cupertino)
    WeatherEntry(date: .now, weather: .cloudy, configuration: .cupertino)
    WeatherEntry(date: .now, weather: .overcast, configuration: .cupertino)
    WeatherEntry(date: .now, weather: .rainy, configuration: .cupertino)
    WeatherEntry(date: .now, weather: .lightning, configuration: .cupertino)
    WeatherEntry(date: .now, weather: .snowy, configuration: .cupertino)
}
PreviousBuilding WidgetsNextSwiftUI

Last updated 1 year ago

Was this helpful?

πŸŽ›οΈ
πŸ‘¨β€πŸ’»