首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无触觉反馈

无触觉反馈
EN

Stack Overflow用户
提问于 2017-02-20 17:39:38
回答 2查看 1.7K关注 0票数 3

我的手表操作系统应用程序依赖于后台的触觉反馈。我在网上搜索和搜索了如何做到这一点,并且只学会了如何在我的info.plist中添加东西。

我不想使用通知通知我的用户,因为它在UI方面很麻烦,因为这样做太频繁了。

我读过关于锻炼的文章,但没能让它起作用。

当手腕被降低时,我如何允许触觉反馈起作用?最简单的方法将是足够的,我不是最先进和迅捷,所以请试着解释充分!

下面是我的代码的一个例子。如果我想让背景触觉反馈起作用,请告诉我放在哪里:

我的计时器:

代码语言:javascript
复制
 _ = Timer.scheduledTimer(timeInterval: 88, target: self, selector: "action", userInfo: nil, repeats: true)

我的行动:

代码语言:javascript
复制
 func action() {
    print("action")
    WKInterfaceDevice.current().play(.success)
     imageObject.setImageNamed("number2")     
}

这就是我对HKWorkout会话所做的,但完全不知道发生了什么。

代码语言:javascript
复制
  func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {
    switch toState {
    case .running:
        workoutDidStart(date)
    case .ended:
        workoutDidEnd(date)
    default:
        print("Unexpected state \(toState)")
    }
}

func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
    // Do nothing for now
    print("Workout error")
}


func workoutDidStart(_ date : Date) {
    if let query = createHeartRateStreamingQuery(date) {
        self.currenQuery = query
        healthStore.execute(query)
    } else {
        label.setText("cannot start")
    }
}

func workoutDidEnd(_ date : Date) {
    healthStore.stop(self.currenQuery!)
    label.setText("---")
    session = nil
}

// MARK: - Actions
@IBAction func startBtnTapped() {
    if (self.workoutActive) {
        //finish the current workout
        self.workoutActive = false
        self.startStopButton.setTitle("Start")
        if let workout = self.session {
            healthStore.end(workout)
        }
    } else {
        //start a new workout
        self.workoutActive = true
        self.startStopButton.setTitle("Stop")
        _ = Timer.scheduledTimer(timeInterval: 5, target: self, selector: "firsts", userInfo: nil, repeats: false)


        startWorkout()
    }

}

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 = .crossTraining
    workoutConfiguration.locationType = .indoor

    do {
        session = try HKWorkoutSession(configuration: workoutConfiguration)
        session?.delegate = self
    } catch {
        fatalError("Unable to create the workout session!")
    }

    healthStore.start(self.session!)
}

func createHeartRateStreamingQuery(_ workoutStartDate: Date) -> HKQuery? {


    guard let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) else { return nil }
    let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil, options: .strictEndDate )
    //let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
    let predicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate])


    let heartRateQuery = HKAnchoredObjectQuery(type: quantityType, predicate: predicate, anchor: nil, limit: Int(HKObjectQueryNoLimit)) { (query, sampleObjects, deletedObjects, newAnchor, error) -> Void in
        //guard let newAnchor = newAnchor else {return}
        //self.anchor = newAnchor
        self.updateHeartRate(sampleObjects)
    }

    heartRateQuery.updateHandler = {(query, samples, deleteObjects, newAnchor, error) -> Void in
        //self.anchor = newAnchor!
        self.updateHeartRate(samples)
    }
    return heartRateQuery
}

func updateHeartRate(_ samples: [HKSample]?) {
    guard let heartRateSamples = samples as? [HKQuantitySample] else {return}

    DispatchQueue.main.async {
        guard let sample = heartRateSamples.first else{return}
        let value = sample.quantity.doubleValue(for: self.heartRateUnit)
        self.label.setText(String(UInt16(value)))

        // retrieve source from sample
        let name = sample.sourceRevision.source.name
        self.updateDeviceName(name)
        self.animateHeart()
    }
}

func updateDeviceName(_ deviceName: String) {
    deviceLabel.setText(deviceName)
}

func animateHeart() {
    self.animate(withDuration: 0.5) {
        self.heart.setWidth(60)
        self.heart.setHeight(90)
    }

    let when = DispatchTime.now() + Double(Int64(0.5 * double_t(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)

    DispatchQueue.global(qos: .default).async {
        DispatchQueue.main.asyncAfter(deadline: when) {
            self.animate(withDuration: 0.5, animations: {
                self.heart.setWidth(50)
                self.heart.setHeight(80)
            })            }


    }
}

听着,我甚至不需要心率数据或其他任何东西,但在背景中的轻声引擎嗡嗡作响。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-02 09:27:31

作为除了我以前的的回答,我创建了一个示例项目,演示如何在后台触发震动:

有关如何使用HKWorkoutSession的完整示例,请查看我在GitHub上的示例项目。即使应用程序在后台运行,样例应用程序也将每5秒触发一次振动。因此,HKWorkoutSession和示例仅在应用程序与包含HealthKit权限的供应配置文件签名时才能工作。确保为所有三个可用目标将开发团队更改为您自己的团队。Xcode将尝试创建所需的配置文件。如果有任何签名问题或使用通配符配置文件,在后台运行将无法工作。

票数 4
EN

Stack Overflow用户

发布于 2017-02-20 18:51:46

这只有使用HKWorkoutSessions才有可能。苹果的watchOS应用程序设计指南清楚地指定了没有HKWorkoutSession的可用背景模式,它们都不允许你在后台触发触觉反馈。

使用HKWorkoutSession,您可以使用应用程序实现跟踪用户锻炼的应用程序。当HKWorkoutSession运行时,您的应用程序具有几个特权:

该应用程序在整个训练过程中继续运行,即使用户降低手腕或与另一个应用程序交互时也是如此。当用户举起手腕时,应用程序就会重新出现,让用户可以快速、轻松地检查他们当前的进度和性能。 该应用程序可以在后台继续访问Apple Watch传感器的数据,使您可以随时更新该应用程序。例如,运行中的应用程序可以继续跟踪用户的心率,确保在用户举起手腕时显示最新的心率数据。 该应用程序可以在后台运行时使用音频或触觉反馈通知用户。

要使用HKWorkoutSession并提供触觉反馈,您需要将WKBackgroundModes键和UIBackgroundModes添加到WatchKit扩展的Info.plist中。

代码语言:javascript
复制
<key>WKBackgroundModes</key>
<array>
    <string>workout-processing</string>
</array>
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>

对此有几个注意事项:

  • 当另一个应用程序启动另一个WKWorkoutSession时,您的会话将被终止。
  • 如果您在后台过度使用资源,您的应用程序可能被watchOS挂起。
  • 您的应用程序可能有助于在配对iPhone上填充活动应用程序中的活动环
  • 根据应用程序类型,苹果在Apple发布时可能会拒绝您的应用程序
  • 需要HealthKit权限(您可以在Xcode中的Capabilities视图中添加它)

有关如何实现HKWorkoutSession的更详细指南,请查看API参考

有关如何使用HKWorkoutSession的完整示例,请查看我在GitHub上的示例项目。即使应用程序在后台运行,样例应用程序也将每5秒触发一次振动。因此,HKWorkoutSession和示例仅在应用程序与包含HealthKit权限的供应配置文件签名时才能工作。确保为所有三个可用目标将开发团队更改为您自己的团队。Xcode将尝试创建所需的配置文件。如果有任何签名问题或使用通配符配置文件,在后台运行将无法工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42351042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档