- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我需要实现一个 WatchKit force-touch MenuItem
来调用一个 saveWorkout()
方法,该方法位于一个单独的类中,该类不是 WKInterfaceController< 的子类
.
我意识到每个类至少需要一个指定的初始化程序。我猜这是关键?
顺便说一句,我的“saveSession() reached”打印语句在使用 sim 时记录到控制台,但在我使用设备时却没有。即使在使用设备时,所有其他打印语句也会记录到控制台。有点奇怪。
我的初始化尝试抛出各种错误,例如:
1.fatal error: use of unimplemented initializer 'init()' for class 'DashboardController'
2.Missing argument for parameter 'context' in call
Dashboard.swift
class DashboardController: WKInterfaceController {
@IBOutlet var timerLabel: WKInterfaceTimer!
@IBOutlet weak var milesLabel: WKInterfaceLabel!
// var wSM: WorkoutSessionManager
//init(wSM: WorkoutSessionManager) {
// self.wSM = wSM
// super.init()
// }
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
addMenuItemWithItemIcon(.Accept, title: "Save", action: #selector(DashboardController.saveSession))
}
override func willActivate() {
super.willActivate()
print("Dashboard controller reached")
}
func saveSession() {
//wSM.saveWorkout()
print("saveSession() reached")
}
WorkoutSessionManager.swift
class WorkoutSessionContext {
let healthStore: HKHealthStore
let activityType: HKWorkoutActivityType
let locationType: HKWorkoutSessionLocationType
init(healthStore: HKHealthStore, activityType: HKWorkoutActivityType = .Other, locationType: HKWorkoutSessionLocationType = .Unknown) {
self.healthStore = healthStore
self.activityType = activityType
self.locationType = locationType
}
}
protocol WorkoutSessionManagerDelegate: class {
// ... protocol methods
}
class WorkoutSessionManager: NSObject, HKWorkoutSessionDelegate {
let healthStore: HKHealthStore
let workoutSession: HKWorkoutSession
init(context: WorkoutSessionContext) {
self.healthStore = context.healthStore
self.workoutSession = HKWorkoutSession(activityType: context.activityType, locationType: context.locationType)
self.currentActiveEnergyQuantity = HKQuantity(unit: self.energyUnit, doubleValue: 0.0)
self.currentDistanceQuantity = HKQuantity(unit: self.distanceUnit, doubleValue: 0.0)
super.init()
self.workoutSession.delegate = self
}
func saveWorkout() {
guard let startDate = self.workoutStartDate, endDate = self.workoutEndDate else {return}
// ...code...
最佳答案
fatal error 是由(或曾经)由这一行引起的:
让 wSM = WorkoutSessionManager()
该行创建了一个新的 WorkoutSessionManager 实例并对其调用了 init()
。
Swift 为任何结构或类提供了一个名为 init()
的默认初始化器,该结构或类为其所有属性提供默认值并且不提供至少一个初始化器本身。但是 WorkoutSessionManager 没有为 healthStore
和 workoutSession
属性提供默认值(并且这些属性不是可选的),它提供了自己的名为 init(context: )
,所以它没有默认初始化器。
您需要使用指定的初始化程序 init(context:)
(传递适当的 WorkoutSessionContext 实例)创建 WorkoutSessionManager 实例,或者为名为 init() 的 WorkoutSessionManager 提供默认初始化程序
。
您执行前者的确切方式取决于应用程序其余部分的实现和 DashboardController 的呈现。我假设您正在尝试重新创建 WWDC 2015 Session 203 中所示的“Fit”应用程序.
在该演示中,初始 Controller 是 ActivityInterfaceController 的一个实例,该 Controller 负责呈现下一个界面(通过 Storyboard中创建的转场)。在ActivityInterfaceController类中可以看到如下代码:
override func contextForSegueWithIdentifier(segueIdentifier: String) -> AnyObject? {
let activityType: HKWorkoutActivityType
switch segueIdentifier {
case "Running":
activityType = .Running
case "Walking":
activityType = .Walking
case "Cycling":
activityType = .Cycling
default:
activityType = .Other
}
return WorkoutSessionContext(healthStore: self.healthStore, activityType: activityType)
}
上面的函数使用初始 Controller 持有的 HKHealthStore 实例创建并返回一个新的 WorkoutSessionContext 实例。该函数返回的上下文通过 awakeWithContext
传递给相关 segue 的目标接口(interface) Controller 。
对于代码中的转换,您可以使用等效函数传递上下文实例,例如 pushControllerWithName(context:)
,这也会导致 awakeWithContext
。
如果您的初始 Controller 与上述类似,您可以在 DashboardController 类的 awakeWithContext
中访问传递的上下文,并使用它来配置 WorkoutSessionManager 的新实例:
class DashboardController: WKInterfaceController
{
// ...
var wSM: WorkoutSessionManager?
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
if context is WorkoutSessionContext {
wSM = WorkoutSessionManager(context: context as! WorkoutSessionContext)
}
addMenuItemWithItemIcon(.Accept, title: "Save", action: #selector(DashboardController.saveSession))
}
// ...
}
以这种方式创建 WorkoutSessionManager 实例可避免调用(不存在的)init()
初始化程序,并允许重用 HKHealthStore 实例。该方法是否对您开放取决于您的其余代码以及您呈现 DashboardController 的方式。
请注意,您应该避免创建 WorkoutSessionManager 的多个实例。使用 singleton提供在您的扩展程序中共享的单个 WorkoutSessionManager 实例。
关于swift - 使用 WatchKit 强制触摸 MenuItem 调用外部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38711226/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!