WatchOS 6.0、Swift 5.0:无背景触觉
Posted
技术标签:
【中文标题】WatchOS 6.0、Swift 5.0:无背景触觉【英文标题】:WatchOS 6.0, Swift 5.0 : No Background Haptics 【发布时间】:2020-03-10 12:35:04 【问题描述】:我正在尝试在应用处于后台时获得触觉反馈。本质上,当某个值超过阈值时,应该有触觉反馈。据我所见,我已经正确设置了所有内容;当超过阈值时我正在调用的函数我知道正在被调用,因为我可以在日志中看到它,但是没有声音或振动发生。所以我不确定我做错了什么。当应用程序显示在屏幕上而不是在后台显示时,它可以正常工作。
这是使用较旧的 Apple 示例代码(我知道折旧的项目)。我的最终目标是拥有一个棒球投球分析应用程序,其触觉是加强学习的肌肉记忆,有点像与狗一起训练的答题器。
这是引入 CoreMotion 的 MotionManager。
import Foundation
import CoreMotion
import WatchKit
import os.log
protocol MotionManagerDelegate: class
func didUpdateMotion(_ manager: MotionManager, gravityStr: String, rotationRateStr: String, userAccelStr: String, attitudeStr: String, rollInt: Double)
extension Date
var millisecondsSince1970:Int64
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
class MotionManager
// MARK: Properties
let motionManager = CMMotionManager()
let queue = OperationQueue()
let wristLocationIsLeft = WKInterfaceDevice.current().wristLocation == .left
// MARK: Application Specific Constants
// The app is using 50hz data and the buffer is going to hold 1s worth of data.
let sampleInterval = 1.0 / 50
let rateAlongGravityBuffer = RunningBuffer(size: 50)
weak var delegate: MotionManagerDelegate?
var gravityStr = ""
var rotationRateStr = ""
var userAccelStr = ""
var attitudeStr = ""
var rollInt = 0.0
var recentDetection = false
// MARK: Initialization
init()
// Serial queue for sample handling and calculations.
queue.maxConcurrentOperationCount = 1
queue.name = "MotionManagerQueue"
// MARK: Motion Manager
func startUpdates()
if !motionManager.isDeviceMotionAvailable
print("Device Motion is not available.")
return
os_log("Start Updates");
motionManager.deviceMotionUpdateInterval = sampleInterval
motionManager.startDeviceMotionUpdates(to: queue) (deviceMotion: CMDeviceMotion?, error: Error?) in
if error != nil
print("Encountered error: \(error!)")
if deviceMotion != nil
self.processDeviceMotion(deviceMotion!)
func stopUpdates()
if motionManager.isDeviceMotionAvailable
motionManager.stopDeviceMotionUpdates()
// MARK: Motion Processing
func processDeviceMotion(_ deviceMotion: CMDeviceMotion)
gravityStr = String(format: "X: %.1f Y: %.1f Z: %.1f" ,
deviceMotion.gravity.x,
deviceMotion.gravity.y,
deviceMotion.gravity.z)
userAccelStr = String(format: "X: %.1f Y: %.1f Z: %.1f" ,
deviceMotion.userAcceleration.x,
deviceMotion.userAcceleration.y,
deviceMotion.userAcceleration.z)
rotationRateStr = String(format: "X: %.1f Y: %.1f Z: %.1f" ,
deviceMotion.rotationRate.x,
deviceMotion.rotationRate.y,
deviceMotion.rotationRate.z)
attitudeStr = String(format: "r: %.1f p: %.1f y: %.1f" ,
deviceMotion.attitude.roll,
deviceMotion.attitude.pitch,
deviceMotion.attitude.yaw)
rollInt = deviceMotion.attitude.roll
let timestamp = Date().millisecondsSince1970
os_log("Motion: %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@",
String(timestamp),
String(deviceMotion.gravity.x),
String(deviceMotion.gravity.y),
String(deviceMotion.gravity.z),
String(deviceMotion.userAcceleration.x),
String(deviceMotion.userAcceleration.y),
String(deviceMotion.userAcceleration.z),
String(deviceMotion.rotationRate.x),
String(deviceMotion.rotationRate.y),
String(deviceMotion.rotationRate.z),
String(deviceMotion.attitude.roll),
String(deviceMotion.attitude.pitch),
String(deviceMotion.attitude.yaw))
updateMetricsDelegate();
// MARK: Data and Delegate Management
func updateMetricsDelegate()
delegate?.didUpdateMotion(self,gravityStr:gravityStr, rotationRateStr: rotationRateStr, userAccelStr: userAccelStr, attitudeStr: attitudeStr, rollInt: rollInt)
这是我的 WorkOutMangager,用于控制锻炼会话。我正在调用的函数在最后。它正在从 MotionManagerDelagate 中提取值。
import Foundation
import HealthKit
import WatchKit
import os.log
protocol WorkoutManagerDelegate: class
func didUpdateMotion(_ manager: WorkoutManager, gravityStr: String, rotationRateStr: String, userAccelStr: String, attitudeStr: String)
class WorkoutManager: MotionManagerDelegate
// MARK: Properties
let motionManager = MotionManager()
let healthStore = HKHealthStore()
var rollInt = 0.0
weak var delegate: WorkoutManagerDelegate?
var session: HKWorkoutSession?
// MARK: Initialization
init()
motionManager.delegate = self
// MARK: WorkoutManager
func startWorkout()
// If we have already started the workout, then do nothing.
if (session != nil)
return
// Configure the workout session.
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .tennis
workoutConfiguration.locationType = .outdoor
do
session = try HKWorkoutSession(configuration: workoutConfiguration)
catch
fatalError("Unable to create the workout session!")
// Start the workout session andKAKAHA.watchWatch.watchkitapp device motion updates.
healthStore.start(session!)
motionManager.startUpdates()
if(rollInt < -0.9)
WKInterfaceDevice.current().play(.failure)
os_log("ALERT!!!")
func stopWorkout()
// If we have already stopped the workout, then do nothing.
if (session == nil)
return
// Stop the device motion updates and workout session.
motionManager.stopUpdates()
healthStore.end(session!)
// Clear the workout session.
session = nil
// MARK: MotionManagerDelegate
func didUpdateMotion(_ manager: MotionManager, gravityStr: String, rotationRateStr: String, userAccelStr: String, attitudeStr: String, rollInt: Double)
delegate?.didUpdateMotion(self, gravityStr: gravityStr, rotationRateStr: rotationRateStr, userAccelStr: userAccelStr, attitudeStr: attitudeStr)
self.rollInt = rollInt
rollAlert()
@objc fileprivate func rollAlert()
if (rollInt < -0.9)
WKInterfaceDevice.current().play(.failure)
os_log("TOO CLOSE TO FACE!!!")
【问题讨论】:
此外,无论多长时间后,应用“唤醒”时都会播放触觉。 【参考方案1】:我觉得自己很愚蠢。我没有选择“音频”作为背景模式。
【讨论】:
以上是关于WatchOS 6.0、Swift 5.0:无背景触觉的主要内容,如果未能解决你的问题,请参考以下文章
Objective C iOS 项目 + Swift 2 WatchOS 项目和 Cocoapods
没有这样的模块错误“NotificationCenter”WatchOS,Swift