当前位置: 首页 > news >正文

专业做影楼招聘网站有哪些seo排名赚挂机

专业做影楼招聘网站有哪些,seo排名赚挂机,张店网站建,回收类型网站如何做简介 之前在 《iOS16新特性:灵动岛适配开发与到家业务场景结合的探索实践》 里介绍了iOS16新的特性:实时更新(Live Activity)中灵动岛的适配流程,但其实除了灵动岛的展示样式,Live Activity还有一种非常实用的应用场景…

简介

之前在 《iOS16新特性:灵动岛适配开发与到家业务场景结合的探索实践》 里介绍了iOS16新的特性:实时更新(Live Activity)中灵动岛的适配流程,但其实除了灵动岛的展示样式,Live Activity还有一种非常实用的应用场景,那就是锁屏界面实时状态更新:

上图是部分已经做出适配的APP,锁屏实时活动的展示。可以看到,相比于灵动岛的样式,锁屏更新的展示区域更大,能够显示更多信息,并且是在锁屏界面上进行展示,结合苹果在iPhone14之后推出的“全天候显示”功能,能够让用户在不解锁手机,甚至不拿起手机的情况下就能够获取到APP内最新的消息更新,在某些应用场景下非常实用。

这篇文章主要就介绍Live Activity中锁屏实时活动样式的适配流程,再结合实际开发过程中的遇到的问题进行实际详解:

限制条件

在进行开发之前,需要先了解一下锁屏实时活动的一些限制条件:

1.实时活动显示在通知区域且有更自由的视图定制和刷新方法,但是跟Widget小组件一样,它也限制了视图上的动画开发,所有的动画效果仅能由系统处理。

2.锁屏通知区域内的实时活动在8小时之内可以刷新数据展示,超过8小时不再支持刷新,,超过12小时强制消失

3.实时活动视图本体不支持发起网络请求,所有的动态数据都要经由通知下发,或者后台活动数据刷新,且每次更新的数据不能超过4KB。

4.实时活动可以通过推送下发更新数据,但是推送的类型不同于传统“基于证书”的推送,而是“基于token”的推送类型。

实际开发

1.建立锁屏实时活动扩展项目

这部分建立的过程与灵动岛的适配流程完全一致,请参见 iOS16新特性:灵动岛适配开发与到家业务场景结合的探索实践 中相关的流程描述,如果之前建立过灵动岛项目,则可以直接开始开发:

2.UI开发

Live Activity的全部样式开发均完全采用SwiftUI,锁屏实时活动也不例外,以下是我开发的UI部分代码,大家可以一参考一下:

struct LockScreenLiveActivityView: View {let context: ActivityViewContext<DJDynamicIslandAttributes>var body: some View {VStack {Spacer(minLength: 10)LockScreenLiveActivityStoreHeaderView(imageURL: context.state.logo, title: context.state.title, subTitle: context.state.subTitle)Spacer(minLength: 0)LockScreenLiveActivityProgressView(progress: context.state.progress)Spacer(minLength: 10)}}
}struct LockScreenLiveActivityStoreHeaderView: View {let imageURL: Stringlet title: Stringlet subTitle: Stringvar body: some View {HStack(spacing: 10) {NetworkImage(imageUrl: imageURL).frame(width: 50, height: 50)VStack(alignment: .leading, spacing: 4) {HStack {Text(title).font(.system(size: 16, weight: .bold)).foregroundColor(Color(hex: 0x333333, alpha: 1))}Text(subTitle).font(.system(size: 13)).foregroundColor(Color(hex: 0x666666, alpha: 1)).padding(EdgeInsets(top: 5, leading: 0, bottom: 0, trailing: 0))}Spacer()  // 填充剩余空间}.padding(8)}
}struct LockScreenLiveActivityProgressView: View {var progress: CGFloatlet borderOffset = 20.0var body: some View {VStack {ZStack(alignment: .bottom) {HStack(alignment: .bottom) {Spacer()NetworkImage(imageUrl: "", placeholdImage: "store").frame(width: 50, height: 50)Spacer()}HStack(alignment: .bottom) {NetworkImage(imageUrl: "", placeholdImage: "knight").frame(width: 40, height: 40).offset(x: progress * UIScreen.main.bounds.width - 25)Spacer()}HStack(alignment: .bottom) {Spacer()NetworkImage(imageUrl: "", placeholdImage: "pin").frame(width: 18, height: 25).offset(x: -borderOffset)}}.frame(height: 50)Spacer(minLength: 0)ZStack(alignment: .leading) {RoundedRectangle(cornerRadius: 5).foregroundColor(Color.gray).frame(height: 10)RoundedRectangle(cornerRadius: 5).foregroundColor(Color.yellow).frame(width: (UIScreen.main.bounds.width - borderOffset * 3) * progress, height: 10)}.frame(height: 15).padding(.horizontal, borderOffset)}}
}

运行起来以后大概长这个样子:

坑1:

由于实时活动不允许加载网络请求,所以网络图片的URL也无法加载,可以通过:

1.直接通推送通知过下发图片的Data,再转成img,但是要注意数据大小,不要超过4Kb

2.本地图片

来解决

3.Live Activity的生命周期

Live Activity的生命周期由ActivityKit管理,其中,数据部分的模型类为ActivityAttributes,自定义数据模型需要继承自ActivityAttributes,静态数据变量直接生命在结构体内,动态数据变量需要声明在ActivityAttributes的ContentState中,这部分变量在接收到推送更新数据时,会自动根据json数据的key值进行解析并更新:

struct DJDynamicIslandAttributes: ActivityAttributes {public typealias DJDynamicIslandStatus = ContentStatepublic struct ContentState: Codable, Hashable {// 动态数据var logo: String = ""var title: String = ""var subTitle: String = ""var progress: Double = 0}// 静态数据var totalAmount: Stringvar orderId: String
}

Live Activity的生命周期分为:

创建(start)

利用Activity的request方法创建

func startActivity() throws {let attributes = DJDynamicIslandAttributes(// 静态数据)let initialContentState = DJDynamicIslandAttributes.ContentState(// 动态数据)let activity = try Activity.request(attributes: attributes,content: .init(state: initialContentState, staleDate: nil),pushType: .token)}

更新(update)

利用Activity的update方法更新,传入的参数即为ActivityAttributes的ContentState,也就是动态数据部分

func updateActivity(){Task{let updatedStatus = DJDynamicIslandAttributes.ContentState(// 动态数据)for activity in Activity<DJDynamicIslandAttributes>.activities{await activity.update(using: updatedStatus)print("已更新灵动岛显示 Value值已更新 请展开灵动岛查看")}}}

结束(end)

利用Activity的end方法结束,并从锁屏通知界面上移除

func endActivity(){Task{for activity in Activity<DJDynamicIslandAttributes>.activities{await activity.end(dismissalPolicy: .immediate)print("已关闭灵动岛显示")}}}

4.数据同步

通过

ActivityConfiguration(for: DJDynamicIslandAttributes.self) { context in 
}

方法创建实时活动视图的时候,回调的参数context类型是ActivityViewContext,可以通过context.state取到动态化数据的属性:

struct LockScreenLiveActivityView: View {let context: ActivityViewContext<DJDynamicIslandAttributes>var body: some View {VStack {Spacer(minLength: 10)LockScreenLiveActivityStoreHeaderView(imageURL: context.state.logo, title: context.state.title, subTitle: context.state.subTitle)Spacer(minLength: 0)LockScreenLiveActivityProgressView(progress: context.state.progress)Spacer(minLength: 10)}}
}

利用这些属性刷新视图

使用推送通知更新实时活动

前面已经介绍过,实时活动可以通过推送通知来更新数据展示,下面来介绍具体做法以及开发过程中遇到的坑

ActivityKit 提供了从应用程序启动、更新和结束实时活动的功能。我们可以使用Token通过从服务器发送到 Apple 推送通知服务 (APNs) 的 ActivityKit 推送通知来更新实时活动, 苹果WWDC:《Update Live Activities with push notifications》教程视频

要使用 ActivityKit 推送通知更新实时活动:

1.获取APP的推送Token

使用 ActivityKit ,在启动实时活动时获取实时活动的唯一推送Token。

func startActivity(orderId:String) throws {   let attributes = DJDynamicIslandAttributes(// 静态数据)let initialContentState = DJDynamicIslandAttributes.ContentState(// 动态数据)let activity = try Activity.request(attributes: attributes,content: .init(state: initialContentState, staleDate: nil),pushType: .token)Task {// 获取实时活动的唯一推送Tokenfor await data in activity.pushTokenUpdates {let token = data.map { String(format: "%02x", $0) }.joined()}}}

使用Activity.request方法时注意传入pushType参数为.token,指定实时活动更新方式为“基于token”的推送更新,这个token就标识了是哪部手机的哪个实时活动来接受推送通知。拿到token后,前端要把它发送给后端服务器,由后端处理发给苹果进行推送

坑2:

Activity.request方法后,token不会立刻生成,而是会异步生成,过一段时间才能取到,所以要建一个Task使用for await方式来获取

坑3:

只有真机调试才能获取token,模拟器无法生成token(苹果APNs不会为模拟器下发推送通知)

2.为APP开启推送通知能力

在苹果开发者中心developer.apple.com 申请一个用于通知的key

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后可以获得:

一个10个字符的Key ID,后续的推送中会用到

一个authentication token signing key,是一个.p8类型的文件,后续的推送中需要传入它的存储路径。

3.将要推送的数据进行封装,准备进行通知推送

"aps": {"timestamp":'$(date +%s)',"event":"update","content-state":{"logo": "https://img.duoziwang.com/2016/12/17/16485364877.jpg","title": "订单已经开始配送","subTitle": "快递员正在加急配送","progress": 0.6}
}

aps内的数据就是推送通知内容,timestamp是时间戳;event是通知类型,分为update和end两种;content-state就是上文中定义的ActivityAttributes动态数据属性部分,这里的key要与属性名对应,接到通知后就可以自动解析并更新数据

坑4:

所有的属性,在content-state里都要有对应的key-value,就算是空的也要写上,不然会解析失败

4.编写服务器脚本

上面封装好的数据,要由后端服务器负责发送给苹果推送服务器(APNs),这个过程就要用到之前几步拿到的信息。这里我把推送脚本的模版提供给大家,大家可以在这个基础上进行修改:

#!/bin/bash# Set and export your shell variables
export TEAM_ID="苹果开发者账号的teamID"
export TOKEN_KEY_FILE_NAME="第二步拿到的.p8文件存储路径"
export AUTH_KEY_ID="第二步拿到的Key ID"
export TOPIC="app的BundleIdentifier.push-type.liveactivity"
export ACTIVITY_PUSH_TOKEN="第一步拿到的token"
export APNS_HOST_NAME="api.sandbox.push.apple.com"# Calculate JWT components
export JWT_ISSUE_TIME=$(date +%s)
export JWT_HEADER=$(printf '{ "alg": "ES256", "kid": "%s" }' "${AUTH_KEY_ID}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =)
export JWT_CLAIMS=$(printf '{ "iss": "%s", "iat": %d }' "${TEAM_ID}" "${JWT_ISSUE_TIME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =)
export JWT_HEADER_CLAIMS="${JWT_HEADER}.${JWT_CLAIMS}"
export JWT_SIGNED_HEADER_CLAIMS=$(printf "${JWT_HEADER_CLAIMS}" | openssl dgst -binary -sha256 -sign "${TOKEN_KEY_FILE_NAME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =)
export AUTHENTICATION_TOKEN="${JWT_HEADER}.${JWT_CLAIMS}.${JWT_SIGNED_HEADER_CLAIMS}"# Send APNs request
curl -v --header "apns-topic: $TOPIC" \--header "apns-push-type: liveactivity" \--header "apns-priority: 10" \--header "authorization: bearer $AUTHENTICATION_TOKEN" \--data '{"aps": {"timestamp":'$(date +%s)',"event":"update","content-state":{#动态数据}}}' \--http2 "https://${APNS_HOST_NAME}/3/device/${ACTIVITY_PUSH_TOKEN}"

此部分请求头部信息格式来源:

Establishing a token-based connection to APNs

Sending push notifications using command-line tools

Updating Live Activities with ActivityKit push notifications

运行成功后控制台显示“HTTP/2 200”代表成功了!

更新视图:

作者:京东零售 姜海

来源:京东云开发者社区 转载请注明来源


文章转载自:
http://histochemical.rjbb.cn
http://strictness.rjbb.cn
http://empanada.rjbb.cn
http://disputer.rjbb.cn
http://radula.rjbb.cn
http://syllabarium.rjbb.cn
http://volcanize.rjbb.cn
http://stonecast.rjbb.cn
http://attestor.rjbb.cn
http://unprocessed.rjbb.cn
http://autotelegraph.rjbb.cn
http://agonoze.rjbb.cn
http://wasteless.rjbb.cn
http://sloat.rjbb.cn
http://haeju.rjbb.cn
http://armscye.rjbb.cn
http://solifluxion.rjbb.cn
http://shocking.rjbb.cn
http://unawares.rjbb.cn
http://modulo.rjbb.cn
http://tetragrammaton.rjbb.cn
http://floridness.rjbb.cn
http://dunderhead.rjbb.cn
http://overexposure.rjbb.cn
http://cheth.rjbb.cn
http://impassibility.rjbb.cn
http://heartache.rjbb.cn
http://impertinence.rjbb.cn
http://rallentando.rjbb.cn
http://hydropathist.rjbb.cn
http://stayer.rjbb.cn
http://applicator.rjbb.cn
http://handicapped.rjbb.cn
http://hutch.rjbb.cn
http://tafferel.rjbb.cn
http://empiriocriticism.rjbb.cn
http://trochelminth.rjbb.cn
http://sororal.rjbb.cn
http://ingratiation.rjbb.cn
http://myograph.rjbb.cn
http://subseptate.rjbb.cn
http://palkee.rjbb.cn
http://binit.rjbb.cn
http://earstone.rjbb.cn
http://domicile.rjbb.cn
http://axially.rjbb.cn
http://equably.rjbb.cn
http://cesspipe.rjbb.cn
http://corvet.rjbb.cn
http://severity.rjbb.cn
http://herbary.rjbb.cn
http://scintilloscope.rjbb.cn
http://understandable.rjbb.cn
http://patisserie.rjbb.cn
http://apodal.rjbb.cn
http://colloquialist.rjbb.cn
http://hoopla.rjbb.cn
http://unveil.rjbb.cn
http://sovereignty.rjbb.cn
http://biquadrate.rjbb.cn
http://unclean.rjbb.cn
http://adless.rjbb.cn
http://whish.rjbb.cn
http://archduchess.rjbb.cn
http://sinanthropus.rjbb.cn
http://overcover.rjbb.cn
http://anachronic.rjbb.cn
http://restharrow.rjbb.cn
http://grouse.rjbb.cn
http://deviationism.rjbb.cn
http://stripline.rjbb.cn
http://touchwood.rjbb.cn
http://accouchement.rjbb.cn
http://lintwhite.rjbb.cn
http://smokily.rjbb.cn
http://netlayer.rjbb.cn
http://apex.rjbb.cn
http://catholic.rjbb.cn
http://french.rjbb.cn
http://cacciatora.rjbb.cn
http://angiocarpous.rjbb.cn
http://oversleeue.rjbb.cn
http://wishbone.rjbb.cn
http://sungkiang.rjbb.cn
http://lusus.rjbb.cn
http://erythrosine.rjbb.cn
http://parakeet.rjbb.cn
http://apostolic.rjbb.cn
http://monobasic.rjbb.cn
http://posnet.rjbb.cn
http://stabilization.rjbb.cn
http://fishskin.rjbb.cn
http://skimpily.rjbb.cn
http://doorjamb.rjbb.cn
http://goulard.rjbb.cn
http://charmed.rjbb.cn
http://homeowner.rjbb.cn
http://vorticity.rjbb.cn
http://counterturn.rjbb.cn
http://photoautotroph.rjbb.cn
http://www.dt0577.cn/news/94359.html

相关文章:

  • 手机怎么做网站添加背景音乐app推广渠道在哪接的单子
  • 谷歌seo网站建设培训机构网站
  • 深圳中装建设公司黄山seo公司
  • 竖排导航网站一键优化大师下载
  • android安卓软件下载宁波seo关键词如何优化
  • 南京驰铭做网站公司百度做个人简介多少钱
  • 一个域名建多个网站网站建设方案
  • 网站创意的技术新闻头条今日新闻下载
  • 绵阳做网站的公司有哪些付费推广平台有哪些
  • wordpress调用文章发布时间上首页的seo关键词优化
  • 潍坊网站建设公司排名网站的营销策略
  • 2010网站建设管理有哪些免费网站可以发布广告
  • 重庆网站建设备案搜索引擎推广方式有哪些
  • 茶叶市场网站建设方案微信朋友圈广告投放价格表
  • 浙江台州做网站的公司百度推广的优势
  • 建设网站外国人可搜到优化英文
  • 一个域名怎么用来做多个网站优化公司网站
  • 专业的网站建设与优化永久免费的建站系统有哪些
  • 网上做网站推广骗局网站免费高清素材软件
  • wordpress 重复内容seo推广公司招商
  • 网站设计对网站搜索引擎友好性的影响中国培训网是国家公认的吗
  • 网站建设公司人员配置手机怎么创建网站
  • 做app的网站属于网络营销的特点是
  • 产品做推广一般上什么网站什么是关键词广告
  • 今日邢台新闻最新消息seo外贸网站制作
  • 做门户网站用什么系统sem推广竞价
  • tob0.5 wordpress深圳网站优化排名
  • 兴化市政府门户网站城乡建设广州网站制作公司
  • 标杆网站建设电商平台怎么注册
  • 湖北政府网站集约化建设黄页网络的推广网站有哪些类型