1.前言
上一篇我们实现了AppleWatch实时获取心率并发送到iOS设备中显示。这一篇将介绍Apple Watch显示自定义UI的推送消息,效果如图:
这篇的demo代码也是在上一篇demo代码基础上进行,当然这篇跟之前的代码没有任何联系,你也可以创建新的项目。
2.测试推送文件
为了方便测试推送,我们创建一个apns文件:File->New->File,选择Empty,创建PushNotificationPayload.apns,内容为:
{
"aps": {
"alert": {
"title": "Silver Salmon Creek",
"body": "开始检测心率吧"
},
"category": "myCategory",
"thread-id": "5280"
},
"Simulator Target Bundle": "com.ihunyu.MyHeartRate.watch"
}
内容为json格式,其中Simulator Target Bundle的值需要是wath应用的bundle id。此时运行Watch项目,点击数码表冠,将WatchApp置于后台,再将PushNotificationPayload.apns文件用鼠标或触控板拖到Watch模拟器上,此时即可测试推送效果:
但此时的样式是系统默认,显示App icon以及在apns文件中定义的title和body。下面我们将改为自定义的UI
3.自定义推送消息UI
创建自定义UI的View,命名为NotificationView.swift,完整文件为:
import SwiftUI
struct NotificationView: View {
let message:String
var body: some View {
VStack {
Image(systemName: "heart.fill")
.resizable()
.frame(width: 100,height: 100)
.foregroundColor(.red)
Text("\(message)")
.font(.headline)
}
}
}
#Preview {
NotificationView(message: "开始检测心率吧")
}
即我们的自定义UI显示一个爱心的Image和推送的文字。
4.配置为显示自定义UI
创建Swift文件,命名为NotificationController.swift,完整内容为:
import WatchKit
import SwiftUI
import UserNotifications
class NotificationController: WKUserNotificationHostingController<NotificationView> {
var message:String!
override var body: NotificationView {
return NotificationView(message: message)
}
override func didReceive(_ notification: UNNotification) {
let content = notification.request.content
message = content.body
}
}
打开MyHeartRateApp.swift文件,
- 在init方法中,添加请求消息推送权限
- 在body方法中添加WKNotificationScene
完整代码为:
import SwiftUI
import UserNotifications
@main
struct MyHeartRate_Watch_AppApp: App {
let center = UNUserNotificationCenter.current()
init() {
center.requestAuthorization(options: [.alert,.sound,.badge]) { (granted, error) in
if let error: Error {
print(error)
}
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
WKNotificationScene(
controller: NotificationController.self, category: "myCategory")
}
}
注意WKNotificationScene中,category参数值需要与apns文件中的category对应的值一致。
5.运行效果
重新运行Watch项目,将Watch App置于后台,将apns文件拖进模拟器中。此时我们看到消息已经以我们定义的UI形式展现了:
6.定时触发消息
我们希望每天早上8点,提醒用户检测心率,我们只要创建定时的本地推送即可。为了方便测试,这里示例代码是在APP启动后15秒后即发送一次本地推送,可以自己实现每天固定时间触发。
/// 添加推送
func setupPush() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
if granted {
let content = UNMutableNotificationContent()
content.title = "Detection Started"
content.body = "开始检测心率吧"
content.categoryIdentifier = "myCategory"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 15, repeats: false)
let request = UNNotificationRequest(identifier: "myCategory", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
}
}
当然也可以用远程推送,由服务器决定什么时候提醒用户进行心率检测,推送相关知识推荐这篇文章