LoginSignup
0
1

More than 1 year has passed since last update.

Widget ExtensionのWidgetファイルからProviderを切り離すとReference to invalid associated typeが出るエラーの対処法

Posted at

iOSでウィジェットの実装をする時に、Widget Extensionを追加すると思うのですが、自動生成されるWidgetのファイル内に複数の構造体が含まれており、別ファイルに分割して整理しようと思いました。
その際にエラーが発生したのでその対処法を記載します。

環境

  • Xcode 14.2
  • iOS 16.2

エラー再現方法

Widget.swift

Widget Extensionを追加すると、Widget Extensionの名前.swiftという名前で自動生成されるファイルです。

今回は例としてSimpleWidget.swiftとします。

SimpleWidget.swift
import WidgetKit
import SwiftUI

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date())
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date())
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate)
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
}

struct SimpleWidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.date, style: .time)
    }
}

struct SimpleWidget: Widget {
    let kind: String = "SimpleWidget"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            SimpleWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

struct SimpleWidget_Previews: PreviewProvider {
    static var previews: some View {
        SimpleWidgetEntryView(entry: SimpleEntry(date: Date()))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

このファイルからProvider構造体を別ファイルに切り出します。

Provider.swift
import WidgetKit

struct Provider: TimelineProvider {
            
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date())
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date())
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate)
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

新規作成したファイルのターゲットはデフォルトでアプリの方のターゲットになっている為、ファイルにターゲットをWidget Extensionに変更します。

widget-target-change-2.png

ファイルを切り出すとgetTimeLineメソッドの引数内のTimeline<Entry>に対して、
Reference to invalid associated type 'Entry' of type 'Provider'
というエラーメッセージが表示されるようになってしまいます。

entry-error.png

対処法

エラーの内容

参照しているEntryは無効なassociated typeだよという内容になります。

typealiasを追加する

typealiasを追加するとエラーが消えます。

Provider.swift

struct Provider: TimelineProvider {
    
    typealias Entry = SimpleEntry
               
// 省略

おわりに

Widget.swiftが自動生成された時にはエラーは出ないのに、ファイルを切り出すとエラーが吐かれるのはどうしてなのだろうか、、🤔

一つのファイルの中に、下記5つが揃っている時にはassociated type参照エラーが出力されない。

  • TimelineProvider
  • TimelineEntry
  • View
  • Widget
  • PreviewProvider

もし、わかる方いましたら優しく教えていただけると嬉しいです🙇

lilossa-eyecatch.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1