ios 如何将Apple Watch Widget扩展添加到现有项目并共享代码?

nkkqxpd9  于 2023-06-07  发布在  iOS
关注(0)|答案(1)|浏览(937)

假设我有一个相当简单的应用程序,为主屏幕和锁定屏幕提供了一个小部件:

struct Provider: IntentTimelineProvider {
    var service = XmlFetcher.shared
    
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(timeIntervalSince1970: 0), configuration: ConfigurationIntent(), town: "Anytown", index: 0.0)
    }
    
    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(timeIntervalSince1970: 0), configuration: configuration, town: "AnyTown", index: 0.0)
        completion(entry)
    }
    
    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        ... do stuff
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationIntent
    
    let town: String
    let index: Float
}

struct OzonWidgetEntryView : View {
    var entry: SimpleEntry
    @Environment(\.widgetFamily) var fam
    
    var body: some View {
        //switch family
        switch fam {
        case .systemSmall: HomeScreenView(entry: entry)
        case .systemMedium: HomeScreenView(entry: entry)
        case .accessoryCircular: CircularView(entry: entry)
        default:
            Text("Hallo Welt")
        }
    }
}

struct OzonWidget: Widget {
    let kind: String = "OzonWidget"
    
    var body: some WidgetConfiguration {
        IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
            OzonWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
        .supportedFamilies([.systemSmall, .systemMedium, .accessoryCircular])
    }
}

struct OzonWidget_Previews: PreviewProvider {
    static var previews: some View {
        OzonWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), town: "Anytown", index: 0))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    }
}

现在我决定将小部件添加到Apple Watch目标。我会选择一个新的目标,选择watchOS应用程序并将其添加到我现有的应用程序中。然后我将为watchOS小部件扩展添加另一个目标。
现在,我得到了一个新文件夹,其中包含TimelineProvider和Apple Watch小部件的Widget Intent。我不想重写我的时间轴,我想使用已经为主应用程序编写的代码(参见accessoryCircular案例)。有一个苹果文档通过使用预编译器提示来解释这一点,但是该文档似乎在昨晚的主题演讲后消失了。
如何告诉我的Watch Widget目标使用时间轴提供程序和已存在的视图?

bkhjykvo

bkhjykvo1#

我希望这会有所帮助
1.添加WatchKit应用程序目标
1.添加WatchKit扩展目标:类似地,为WatchKit扩展添加另一个目标。再次选择“Apple Watch”类别下的“watchOS”,但这次选择“WatchKit App Extension”作为模板。配置新目标并将其添加到项目中。
1.在目标之间共享代码:要重用现有代码,您可以创建iOS和watchOS目标均可访问的共享文件。在Xcode中,选择要添加共享代码文件的组,然后右键单击并选择“新建文件”。创建Swift文件
1.条件编译:要根据目标区分代码执行,可以使用条件编译指令,如#if os(watchOS)。将watchOS目标特定的代码部分 Package 在这些指令中。例如:

#if os(watchOS)
// Watch-specific code here
#else
// iOS-specific code here
#endif

您可以在现有的TimelineProvider和View代码中使用这些指令来处理特定于watchOS的功能。
1.配置监视小部件目标:在WatchKit Extension目标中,找到ExtensionDelegate.swift文件。在didFinishLaunching()方法中,使用WidgetCenter API配置小部件。您可以将小部件的timelineProvider属性设置为现有TimelineProvider的示例。下面是一个例子:

func applicationDidFinishLaunching() {
    // Configure the widget
    let widgetProvider = Provider()
    let timeline = widgetProvider.getTimeline(for: /* configuration */, in: .main) { timeline in
        WidgetCenter.shared.reloadAllTimelines()
    }
    WidgetCenter.shared.reloadAllTimelines()
    WidgetCenter.shared.currentConfigurations { (configurations) in
        for configuration in configurations {
            WidgetCenter.shared.reloadTimelines(ofKind: "OzonWidget", withConfigurationAt: configuration) 
        }
    }
}

为您的应用程序更新Provider()初始化和对getTimeline(for:in:completion:)的调用。
1.更新视图:在WatchKit Extension目标中,找到ContentView.swift文件并更新视图以使用共享代码。您可以包含共享视图并在适当的小部件系列案例中使用它,例如.circular

case .circular:
    CircularView(entry: entry)

确保导入WatchKit扩展目标文件中的所有必要共享文件。
通过执行这些步骤,您可以在watchOS widget目标中重用iOS应用中的TimelineProvider和View代码。只需确保有条件地编译代码并为watchOS目标适当地配置小部件。

相关问题