一个Android开发学习开发ios桌面小组件

1 创建widget extension

2 创建完成之后 理论上就可以运行了

关键代码包括 TimelineProvider TimelineEntry

正常代码是下面这样的

js 复制代码
//
//  home_widget_study.swift
//  home_widget_study
//
//  Created by gy on 2025/3/7.
//

import WidgetKit
import SwiftUI

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

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), emoji: "😀")
        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, emoji: "😀")
            entries.append(entry)
        }

         //entries 定义了刷新的时间 这里数组长度为5 每个元素的时间相差一小时 意思就是从小组件添加之后一小时刷新一次 好像这个时间不能设置的太短 最短好像是5分钟
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }

//    func relevances() async -> WidgetRelevances<Void> {
//        // Generate a list containing the contexts this widget is relevant in.
//    }
}


//里面的属性可以根据自己的需求 自定义
//但是这个date 好像是必须的 意思是下次刷新的时间 因为小组件不会自己刷新
struct SimpleEntry: TimelineEntry {
    let date: Date
    let emoji: String
}

struct home_widget_studyEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack {
            Text("Time:")
            Text(entry.date, style: .time)

            Text("Emoji:")
            Text(entry.emoji)
        }
    }
}

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

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            if #available(iOS 17.0, *) {
                home_widget_studyEntryView(entry: entry)
                    .containerBackground(.fill.tertiary, for: .widget)
            } else {
                home_widget_studyEntryView(entry: entry)
                    .padding()
                    .background()
            }
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

#Preview(as: .systemSmall) {
    home_widget_study()
} timeline: {
    SimpleEntry(date: .now, emoji: "😀")
    SimpleEntry(date: .now, emoji: "🤩")
}

如果你的TimerLineProvider初始代码如下,运行会报错。你可以参考上面的代码修改调整一下。下面的代码好像是高版本的写法。

js 复制代码
func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(),model: 0)
    }

    func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: configuration,model: "456")
    }
    
    func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
        var entries: [SimpleEntry] = []

        print("timelinetimelinetimelinetimelinetimeline===================")
        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        let userdefaults = UserDefaults(suiteName: "group.com.aiintelligent.iossoftware.homewidget")
        let model = userdefaults?.string(forKey: "model") ?? "model"
        let a = print("==========model===",model)
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .minute, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate,model: model)
            entries.append(entry)
        }

        return Timeline(entries: entries, policy: .atEnd)
    }

如果你的widget body 是如下代码 也参照上面的修改 这个好像也是高版本代码

js 复制代码
var body: some WidgetConfiguration {
        AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
            1EntryView(entry: entry)
                .containerBackground(.fill.tertiary, for: .widget)
        }
    }

3 主动刷新小组件

js 复制代码
WidgetCenter.shared.reloadTimelines(ofKind: "home_widget_study")

ofKind 在这里

4 主程序与小组件之间通信 传递数据

group_name 需要在开发者后台配置 在小组件 跟 主程序使用的group_name一定要一样,切必须是开发者后台配置的值。

js 复制代码
 var userdefaults = UserDefaults(suiteName: "group_name")
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui