初心者がIntent実装で迷いまくった、、AppIntentをとりあえずコピペで実現可

## 実行環境

MacOS Sonoma 14.16.1

Xcode 16.2

Swift 5

## Intentとは？

どうやらバージョンによって種類があるみたいです。今回の下記のスクショで載せているものは`AppIntent`で実装されているものになります。`AppIntent`は[iOS16から導入された実装法](https://developer.apple.com/documentation/appintents/appintent)になります。それまでは、Custom Intentという実装用いてみたいです。[こちらの記事](https://zenn.dev/rnishimu22001/articles/52ef673962b40c101913)でのViewが表示されます。

![スクリーンショット 2024-12-19 0.52.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669320/5bfad306-c3f8-315e-6d81-61085264ef81.png)


## Widgetを作成

今回は[こちらの記事](https://developer.apple.com/jp/documentation/widgetkit/creating-a-widget-extension/)を参考にWidgetを作成してください

## 実装

今回のはただのサンプルで行った実装です。変数名など自身で適宜変更してください。

sampleWidget.swift

```swift
import WidgetKit
import SwiftUI

struct Provider: AppIntentTimelineProvider {
    // ConfigurationAppIntentの型を指定
    typealias Entry = SimpleEntry
    typealias Intent = ConfigurationAppIntent
    
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
    }
    
    func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: configuration)
    }
    
    func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
        let entries = [SimpleEntry(date: Date(), configuration: configuration)]
        return Timeline(entries: entries, policy: .atEnd)
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationAppIntent
}

struct sampleWidgetEntryView : View {
    var entry: Provider.Entry
    
    var body: some View {
        VStack {
            if let selectedDog = entry.configuration.selectedDog {
                Text(selectedDog.rawValue)
                    .font(.system(size: 16, weight: .bold))
            } else {
                Text("犬種を選択してください")
                    .font(.system(size: 16, weight: .bold))
            }
        }
        .padding()
    }
}

struct sampleWidget: Widget {
    let kind: String = "DogWidget"
    
    var body: some WidgetConfiguration {
        AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
            sampleWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("犬種ウィジェット")
        .description("選択した犬種を表示します")
        .supportedFamilies([.systemSmall])
    }
}

extension ConfigurationAppIntent {
    fileprivate static var smiley: ConfigurationAppIntent {
        let intent = ConfigurationAppIntent()
        intent.selectedDog = .tosa
        return intent
    }
    
    fileprivate static var starEyes: ConfigurationAppIntent {
        let intent = ConfigurationAppIntent()
        intent.selectedDog = .chihuahua
        return intent
    }
}

#Preview(as: .systemSmall) {
    sampleWidget()
} timeline: {
    SimpleEntry(date: .now, configuration: .smiley)
    SimpleEntry(date: .now, configuration: .starEyes)
}
```

AppIntent.swift

```swift
import WidgetKit
import AppIntents

struct ConfigurationAppIntent: WidgetConfigurationIntent {
    static var title: LocalizedStringResource = "Dog"
    static var description: IntentDescription = "Select your favorite dog"

    // Parameterの指定を簡略化
    @Parameter(title: "犬種")
    var selectedDog: DogType?

    init() {
        self.selectedDog = .tosa
    }
}

enum DogType: String, CaseIterable, AppEnum {
    case tosa = "土佐犬"
    case dachshund = "ミニチュアダックスフンド"
    case chihuahua = "チワワ"
    
    static var typeDisplayRepresentation: TypeDisplayRepresentation {
        TypeDisplayRepresentation(name: "Dog") // システムイメージを追加
    }
    
    static var caseDisplayRepresentations: [DogType : DisplayRepresentation] {
        [
            .tosa: DisplayRepresentation(title: "土佐犬"),
            .dachshund: DisplayRepresentation(title: "ミニチュアダックスフンド"),
            .chihuahua: DisplayRepresentation(title: "チワワ")
        ]
    }
}

```

## 参考記事

[AppIntent | Apple Developer Documentation](https://developer.apple.com/documentation/appintents/appintent)

[WidgetExtensionで設定を作る](https://zenn.dev/rnishimu22001/articles/52ef673962b40c101913)

[iOS 14 アプリケーションのWidgetの追加（通常のWidget、Intentsを使用した構成可能なWidget) - Qiita](https://qiita.com/mashunzhe/items/d29d58f2204f082d8109)