Widget小组件

news2025/1/16 2:36:52

目录

技能点

Widget背调

a. 设计定位

b. Widget小组件限制

c. Widget小组件 开发须知

d. 什么是 SwiftUI

App Group 数据共享

a. 配置 App Groups

1、开发者账号配置,并更新pp证书

2、Xcode配置

b. 缓存数据共享-代码实现

1、文件存储

2. 沙盒存储(参考WidgetGroupTool类)

c. pod共享

d. 文件共享(详见WidgetGroupTool)

Widget小组件配置

a. 添加Widget

b. 编写Widget

c. 多Widget组件实现

d. 登录及授权

e. 拉起app

f. 埋点

g. 可配置的Widget组件(详见WidgetStudy项目)

h. 动态项配置(容易出错)

i. 配置页面颜色设置

项目应用示例​​​​​​​

技能点

SwiftUI语言

Widget小组件配置

App组之间的数据共享

Widget背调

a. 设计定位

用户可以通过 Widget 对主屏幕进行个性化定制,但是 iOS 14 的 Widget 跟其他系统上的小组件有很大的区别。在 Widget 的设计上苹果也保持了一贯的克制,定位于轻量化、仅用作关键信息的展示。比如系统自带 Widget 中的股票、天气、电量、运动信息,他们的共同特征是更新频率高、提供的信息重要,让用户不用打开 app 就可以浏览关心的内容。苹果也不希望开发者将 Widget 仅仅当作 app 的一个快捷入口,这样的需求更适合用 contextual menu 来实现。

我们想给经销商app的增加多元的入口体验,于是就有了这个需求。

b. Widget小组件限制

苹果基于上面的设计定位,同时也为了节省系统资源保证续航,对 Widget 的做了一些限制:

1、不支持动画,仅支持静态页面展示

2、更新频率由系统通过机器学习来动态分配

3、不支持拖拽、滚动等复杂的交互,不支持 Switch 等控件

c. Widget小组件 开发须知

1、只能使用SwiftUI进行开发,所以需要SwiftUI和Swift基础

2、Widget只支持3种尺寸systemSmall(2x2)、 systemMedium(4x2)、 systemLarge(4x4)

3、默认点击Widget打开主应用程序

4、需要在项目中进行App Groups的设置才能使其与主程序互通数据 

官方设计文档: Widgets - System experiences - Components - Human Interface Guidelines - Design - Apple Developer

d. 什么是 SwiftUI

SwiftUI 于 2019 年度 WWDC 全球开发者大会上发布,它是基于 Swift 建立的声明式框架。该框架可以用于 watchOS、tvOS、macOS、iOS 等平台的应用开发,等于说统一了苹果生态圈的开发工具。

对于 Swift UI,官方的定义很好找到,也写得非常明确:

SwiftUI is a user interface toolkit that lets us design apps in a declarative way.
可以理解为 SwiftUI 就是⼀种描述式的构建 UI 的⽅式。

SwiftUI官方教程:Apple Developer Documentation

App Group 数据共享

Widget小组件属于一个独立的app,它有着和主项目完全不同的bundleId。

Widget小组件中接口请求需要与主项目相同的账号、dealerId、token等信息,于是就需要从一个app中读取另一个app的信息,但是这是不被苹果允许的,所以就有了APP group的概念,可以将同一个开发者账号下的app数据放到同一个缓存组中,这样这些app就可以共享这些信息。

a. 配置 App Groups

1、开发者账号配置,并更新pp证书

 I. 创建两个APP,并且在Apple Developer中创建两个APP的id创建APPid时,在APP Groups复选框打上对钩,当我们配置完成App ID之后,会发现App Groups是Configurable状态,这是因为咱们还没有配置相应的app groups,别着急,咱们等会再来管它。

II. 在id那一组中又一个App Groups选项,我们新创建一个APP Groups,这里一共有两个选项,第一个是我们这个app group的描述,第二个是我们app group的id。这个id默认是要group.打头,并且是不能去掉的。

III. 现在去配置新创建的两个APP ID,因为再创建的时候勾选了APP Groups,但是并没有配置它,所以它回事黄色的状态,现在点击Edit,进入之后选择新创举的groups。

IV. 点击Edit---勾选上刚创建好的App Group----配置完成,在返回来看一下咱们的App ID,完美~Enabled状态了.

2Xcode配置

主项目和Widget Extension添加App Groups

Capabilities->App Groups

当我们配置完以后,会在文件目录下多出来一个.entitlements的文件

b. 缓存数据共享-代码实现

1、文件存储

主项目写入数据

widget读取数据

2. 沙盒存储(参考WidgetGroupTool类)

写入数据

I. 传统方法 

II. 新方法  (swift属性包装器)

读取数据  

c. pod共享

​​​​​​​

d. 文件共享(详见WidgetGroupTool

Widget小组件配置

a. 添加Widget

File -> New -> Target -> Widget Extension

Include Configuration Intent如果你所创建的Widget需要支持用户自定义配置属性,则需要勾选这个(例如天气组件,用户可以选择城市;记事本组件,用户记录信息等),不支持的话则不用勾选

会生成一个新文件夹,包含以下内容

  • 扩展名.swift
  •  扩展名.intentdefinition(勾选Include Configuration Intent)
  • Assets.xcassets
  • Info.plist

b. 编写Widget

1、原理:开发者通过 SwiftUI 构建 Views,定义Timelines为 Views 提供对应时间所需的数据,当数据变化时,通过reload更新数据。TimelineProvider提供一组TimelineEntry和ReloadPolicy,用来后续刷新页面。

2、实现 Widget 的代码相对比较模版,可以从 Widget 的入口开始,缺什么补什么。

I. 入口:@main

  •  @main:代表着Widget的主入口,系统从这里加载,可用于多Widget实现
  •  kind:字符串,唯一标识 Widget。
  • WidgetConfiguration:有两类配置,分别为
    •  StaticConfiguration : 可以在不需要用户任何输入的情况下自行解析,可以在 Widget 的 App 中获取相关数据并发送给 Widget。
    •  IntentConfiguration:依赖于 App 的 Siri Intent,会自动接收这些 Intent 并用于更新 Widget,用于构建动态 Widget。
  • .supportedFamilies:支持不同尺寸。
  •  description:添加编辑界面展示的描述内容
  • configurationDisplayName:添加编辑界面展示的标题

II. Entry

渲染 Widget 所需的数据模型,需要遵守TimelineEntry协议。

III. Provider

遵守TimelineProvider协议,告诉 WidgetKit 何时渲染与刷新 Widget。需要实现以下 3 个方法

placeholdergetSnapshotgetTimeline

  1.  getTimeline 是最重要的方法,后面的数据刷新都会在其中完成,所以可能会在其中完成最新的网络数据和本地数据的获取,然后转成 Model 以供使用。
  2.  getTimeline 的方法里有一个 policy 参数,表示刷新的时机,可以选择.never(不刷新),.atEnd(Entry 显示完毕之后自动刷新) 或 .after(date)(到达某个特定时间后自动刷新)。
  3.  Widget 刷新的时间由系统统一决定(有时候设置了也不会自己刷新),如果需要强制刷新 Widget,可以在 App 中使用 WidgetCenter 来重新加载所有时间线:WidgetCenter.shared.reloadAllTimelines()

IV. EntryView

屏幕上 Widget 显示的内容,可以针对不同尺寸的 Widget 设置不同的 View。

  1.  Widget 能且只能使用 SwiftUI 构建界面。
  2.  Widget 本质:一个随着时间线而更新的 SwiftUI View。

c. 多Widget组件实现

一个Widget只能实现大中小三个不同尺寸的组件形式,如果现有需求要做不同功能并且相同尺寸规格的组件则需要实现多组件。

通过修改原Widget入口文件方法添加更多配置来支持多个Widget

每个bundle body子属性上限为5个

d. 登录及授权

加载数据之前首先要解决的是授权问题。

1、主 app 在登录后将 token 等数据写入 app group 中

2、Widget 通过 HTTPS 接口加上 token 来访问用户数据。其中 token 通过 UserDefaults 来共享到 Widget,因为开发过程中不同的证书打包的 bundle id 不同,因此我们将 group name 设置成 group.[bundle id] 的形式,保证能正确读取 token。

Token 的同步有几个时机:

  1.  App 启动后,更新token
  2.  登录成功,更新token
  3.  退出登录时,删除 token

e. 拉起app

苹果提供了两种 API 给到开发者,第一种是SwiftUI 的 WidgetURL API,它的可点击区域是在整个widget页面。

对于 systemSmall 类型来说,只支持 widgetURL 的方式,但是对于 systemMedium 和 systemLarge 还可以使用 SwiftUI Link API,而 Link 的可点击区域是这样的: 

f. 埋点

Widget 的曝光事件我们是无法感知的,由于点击 Widget 会直接跳转到主 app,所以我们可以在跳转到主 app 的 URL 上增加埋点参数,主 app 解析 URL 中的参数来埋点。

触发网络请求的时候,也可以考虑添加埋点。

g. 可配置的Widget组件(详见WidgetStudy项目)

前面我们所介绍的构建小组件的方式,虽然可以通过时间线做部分更新逻辑,但对用户来说,依然是静态的。用户不能够根据自己的偏好对组件进行配置,还以天气类组件为例,有些用户可能关心的是空气质量,湿度等信息,有些用户可能只关心阴天雨天的信息,由于小组件的显示空间有限,有时候你无法将所有的信息都展示在组件内,因此让用户选择他感兴趣的信息进行小组件的配置非常重要。

首先,如果要让我们开发的Widget可以支持用户配置,需要在Widget的target工程中添加一个配置属性表文件,使用Xcode新建一个SiriKit Intent Definition File的文件,如下图所示:

之后,需要创建一个新的Intent配置,添加一系列的用户配置项,系统提供了各种类型的配置项,如让用户传入字符串信息的配置项,开关配置项,日期配置项等等,如下图所示:

重新运行Widget,我们的小组件就已支持用户配置功能,用户可以编辑小组件进行设置,当用户修改了配置项后,组件会重新请求Timeline时间线,在timeline回调方法中,会传入configuration对象,用来存储用户的配置信息

(添加枚举属性,修改display name)

需要注意以下几点:

  •  Intent 的 Category 选择为 View(即用于展示/配置 UI)
  •  选中 Intent is eligible for widgets
  •  取消选中 Siri can ask value for run(除非该 Intent 也用于 Siri Shortcuts)

同时需要修改Provider,改为遵循IntentTimelineProvider(详见Widget2)

h. 动态项配置(容易出错)

上面演示的这种配置方式,适用于当配置项固定的场景,更多时候,可能连配置项都是动态的,比如我们的应用会根据服务端的状态来提供不同的服务,这时可提供给用户开启的服务项目就是动态的。Widget的配置项也支持动态进行配置,这需要使用到Intents Extension的相关功能,下图为动态项配置

添加Intents Extension官方文档

IntentHandler类遵循对应的IntentHandling协议,并实现provideCardOptionsCollection,defaultCard协议方法

  •  provideCardOptionsCollection(for:with:)在用户点击 Widget 中 Card 配置项的时候,WidgetKit 会展示上图右侧中的列表 UI,其中的数据由这个方法异步返回。
  •  defaultCard(for:)我们可以通过实现该方法,在用户首次添加我们的 Widget 时,对于该 Widget 的某一个可配置项返回一个默认的参数值。例如在图示的实现中,我们返回了用户的主要信用卡(Primary Card)。

Tips:

  •  通过使用 INObjectCollection(sections:) 构造器,传入 INObjectSection 数组,可以分区展示待选项列表。
  •  自定义 Intent 类型继承自 INObject,通过重载/设置 displayString、 subtitleString 等属性,可以定制自定义类型在待选项列表中的显示内容。
  •  Intent Handling 协议中定义的 defaultXXX(for:) 方法被标记为 optional,但是依然推荐实现,因为一个好的默认视图对我们的 Widget 来说是十分重要的。

你可能注意到了待选项列表上方的搜索框。默认情况下,搜索框会对我们所返回的全部内容进行搜索过滤。但是,当待选数据较多,或者说待选数据取决于用户具体输入时,我们可以打开 Intent handler provides search results as the user types 选项,实现对待选项列表的实时更新。

在打开该选项后,Xcode 会为生成的 IntentHandling 协议的 provideCardOptionsCollection(for:with:) 方法添加一个 searchTerm 参数:

当用户在搜索框中输入字符时,WidgetKit 会调用该方法对待选项列表进行更新。首次显示待选项列表时,该参数值为 nil。

i. 配置页面颜色设置

背景色设置

文本按钮颜色配置

项目应用示例

上图为小组件的示例图

上图为添加小组件的步骤演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】运算符及相关函数详解

序号系列文章3【MySQL】MySQL基本数据类型4【MySQL】MySQL表的七大约束5【MySQL】字符集与校对集详解6【MySQL】MySQL单表操作详解文章目录前言MySQL运算符1,算术运算符1.1,算术运算符的基本使用1.2,常用数学函数的基本使用2,比较…

vulnhub DC系列 DC-7

总结:社工尝试 目录 下载地址 漏洞分析 信息收集 ssh webshell 命令执行 提权 下载地址 DC-7.zip (Size: 939 MB)Download: http://www.five86.com/downloads/DC-7.zipDownload (Mirror): https://download.vulnhub.com/dc/DC-7.zip漏洞分析 信息收集 这里还…

代码随想录算法训练营第13天 239.滑动窗口最大值、347. 前 K 个高频元素

代码随想录算法训练营第13天 239.滑动窗口最大值、347. 前 K 个高频元素 滑动窗口最大值 力扣题目链接(opens new window) 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只…

YonBuilder 应用构建教程之移动端扩展

YonBuilder 移动端扩展 在上一篇文章中,我们通过对员工信息实体的移动端页面构建来对 YonBuilder 移动端配置的基础流程进行了简单的介绍,本篇文章则通过之前搭建的出入库实体来进行扩展,主要介绍如何在移动端中添加跳转页面的功能以及通过函…

大连理工大学(开发区校区)2023年新生赛(验题人题解)

难度分布 根据排行榜情况,大致分布如下: Easy:AIDE Middle:CJF Hard:GBH 题解 A. Hello World.(题意实现) 直接输出Hello world. I. lgl想签到(题意实现) 统计周…

组件优化 - 多project方案

背景 经销商项目目前是混合项目,有oc、swift、flutter,并对应各自的一些三方库,并随着需求的增加,项目代码体积也越来越大,编译速度也相应的慢了很多,这也严重影响了开发速度,故目前的期望是可…

Linux:git工具

文章目录一.git的下载二.如何使用git将代码传到远端仓库2.1在gitee上新建一个仓库2.2克隆仓库到本地git clone2.3将文件添加到本地仓库git add2.4将代码提交到本地仓库git commit -m2.5将本地仓库的内容传到远端仓库中git push三.git的一些其它使用3.1git log查看日志3.2git rm…

【魅力开源】第5集:通过Odoo实现将EXCEL表费用明细,快速导入到ERP总账系统生成凭证

文章目录前言一、拿到这样的一张表二、实现过程1. 控制器(Controller)2. 模型(Model)3. 视图(View)4. 返回生成的凭证号最后前言 这是一个小功能。 财务小姐姐每个月需要不少的时间去手录费用凭证,这个功能可以实现将半天一天时间内完成的事情,在1小时内…

204:vue+openlayers 学习Attribution各种API,示例展示自定义版权信息

第204个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers项目中个性化修改版权信息,这里主要涉及到Attribution各种属性的设置,所以这里先列出属性的信息,然后用示例来展示如何使用。 名称类型说明classNamestring (默认为“ol-attribution”)CSS 类名。targetH…

Acwing---1219.移动距离

移动距离1.题目2.基本思想3.代码实现1.题目 X星球居民小区的楼房全是一样的,并且按矩阵样式排列。 其楼房的编号为 1,2,3… 当排满一行时,从下一行相邻的楼往反方向排号。 比如:当小区排号宽度为 6 时,开始情形如下&#xff1a…

使用Anaconda(3-5.1.0对应 python3.6.3)搭建OpenCV(3.5.1.15)环境和Jupyter Notebook

使用Anaconda搭建python和OpenCV环境1、 Anaconda3-5.1.0下载Anaconda3-5.1.0下载链接:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/下载 Anaconda3-5.1.0-Windows-x86_64.exe 对应 python3.6.32、安装Anaconda全程下一步,修改了一下默认安装…

如何学习C++图像处理?

学习C图像处理前首先的明确图像处理是什么,它是如何定义的?它能给我们带来哪些便利?之后根据需求选择合适的编程语言,C or python?图像处理(image processing),用计算机对图像进行分析,以达到所…

你还不知道怎么实现财富自由吗?一篇文章手把手教你入门!

程序猿作为互联网行业的翘楚,压力多多收获也多多。 如果想在上班之余还有外快拿,最好的方法就是利用业余时间做做兼职赚外快,不仅可以充实自己的钱包,还可以磨练自己的技术,一举两得。 找外快可是一门技术活&#xf…

三万秃发人群撑起一个IPO,大麦植发能成功上市吗?

不断壮大的“脱发”大军正撑起植发这一条黄金赛道。据弗若斯特沙利文报告,2020年中国毛发医疗服务的市场规模已达到184亿元,预计到2030年将达到1381亿元,CAGR为22.3%。 由于市场规模增长较快,资本也加强了对植发行业的关注&#…

python实现给pdf文件加骑缝章效果

骑缝章是在合同上经常看到的一种盖章方式,如下图所示。现在电子合同的应用已经越来越广泛,合同上如何实现骑缝章的效果 ,也是有必要研究一下的。本文几乎Python的方式,讲述了如果对印章图片进行处理,然后,实…

JAVA校园闲置物品交易系统源码+数据库,为在校师生提供闲置物品发布、物品查询、物品交易等功能

校园闲置平台 校园闲置物品交易系统,为在校师生提供闲置物品发布、物品查询、物品交易等功能。 使用JAVA编写的(javaweb和ssm) Summary 项目的技术栈项目功能介绍项目运行环境部署项目 项目的技术栈 IoC容器:Spring web框架:SpringMVC (PHP版为ThinkPHP) orm…

不会数学的程序员,只能走到初级开发工程师!

作者:小傅哥 博客:https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获!😄 在我还是初级程序员时,每天也都粘贴着代码和包装着接口。那个阶段并没有意识到数学能在编程中起到什么作用&#xff…

【Java基础】-【集合类】

目录Java中的容器(集合类)Java中的容器,线程安全和线程不安全的分别有哪些?Map接口的实现类Map put的过程如何得到一个线程安全的Map?HashMap的特点JDK7和JDK8中的HashMap有什么区别?HashMap底层的实现原理…

【年度总结】2022回首瞻望 | 2023大展宏“兔“

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计专业大二本科在读,阿里云社区专家博主,华为云社区云享专家,CSDN SAP应用技术领域新兴创作者。   在学习工…

GO语言配置和基础语法应用(三)

C语言是直接影响Go语言设计的语言之一。 Go是一门编译型语言,Go语言的工具链将源代码及其依赖转换成计算机的机器指令(译注:静态编译)。 package mainimport "fmt"func main() {fmt.Println("Hello, 世界")…