将保存的锻炼从Watch传递给iPhone

时间:2016-11-17 00:28:48

标签: swift watchkit health-kit

在观看时,我可以将保存的锻炼从WorkoutInterfaceController传递到SummaryInterfaceController。但我想知道如何将保存的锻炼从Watch传递到iPhone (所以我也可以在摘要视图控制器中显示它)。

你知道吗?或者有更好的方法我应该这样做吗?

以下是我用来将保存的锻炼从WorkoutInterfaceController传递到SummaryInterfaceController

的方法
private func saveWorkout() {
    // Create and save a workout sample
    let configuration = workoutSession!.workoutConfiguration
    let isIndoor = (configuration.locationType == .indoor) as NSNumber
    print("locationType: \(configuration)")

    let workout = HKWorkout(activityType: configuration.activityType,
                            start: workoutStartDate!,
                            end: workoutEndDate!,
                            workoutEvents: workoutEvents,
                            totalEnergyBurned: totalEnergyBurned,
                            totalDistance: totalDistance,
                            metadata: [HKMetadataKeyIndoorWorkout:isIndoor]);

    healthStore.save(workout) { success, _ in
        if success {
            self.addSamples(toWorkout: workout)
        }
    }

    WKInterfaceController.reloadRootControllers(withNames: ["SummaryInterfaceController"], contexts: [workout])
}

private func addSamples(toWorkout workout: HKWorkout) {
    // Create energy and distance samples
    let totalEnergyBurnedSample = HKQuantitySample(type: HKQuantityType.activeEnergyBurned(),
                                                   quantity: totalEnergyBurned,
                                                   start: workoutStartDate!,
                                                   end: workoutEndDate!)

    // Add samples to workout
    healthStore.add([totalEnergyBurnedSample], to: workout) { (success: Bool, error: Error?) in
        if success {
            // Samples have been added
        }
    }
}

如果需要任何问题或信息,请告诉我,谢谢!

2 个答案:

答案 0 :(得分:1)

要做到这一点,你必须创建一个应用程序组,它本质上是一个应用程序可以使用的空间。它与iOS8中的exetension框架一起引入,因此应用程序可以与他们的Today小部件或自定义键盘以及其他应用程序进行通信。

添加功能

我们要做的第一件事是将应用程序组功能添加到我们的iPhone和Watch Watch扩展目标。

要执行此操作,请打开项目设置(文件列表顶部的蓝色图标),然后选择iPhone目标。您需要选择页面顶部的“功能”标签,然后向下滚动以启用应用组。

这需要连接的开发者个人资料,并且需要一段时间才能启用。您还需要执行相同的步骤来为手表套件扩展程序启用应用程序组。

接下来,您需要确保应用程序组字符串是您想要的标识符字符串,这对您的应用程序有意义,它必须以单词组开头或抱怨。如果您愿意,还可以添加多个组。无论你选择什么,他们必须启用蓝色勾号(这可能需要一段时间),并且iPhone和Watch扩展目标都完全相同!

Capabilities Image

要使用应用程序组,它与NSUserDefaults没有区别或难以使用:

var userDefaults = NSUserDefaults(suiteName: "group.com.example.My-App")
userDefaults.setObject(true, forKey: "isDarkModeEnabled")
userDefaults.synchronize()

这里唯一的区别是如何实例化NSUserDefaults并在最后调用synchronize。您将容器ID提供给名为“suiteName”的构造函数参数,然后调用“synchronize()”,您的数据将飞到云端以供其他应用程序和设备使用。

将其提升到新的水平

您可以通过为应用创建一个类并为您的属性抽象底层存储来更进一步。这是一个例子:

public class ConfigurationModel: NSObject {

public static let storageKey = "group.com.example.My-App"
public let userStorage = NSUserDefaults(suiteName: storageKey)

public var isDarkModeEnabled: Bool {
 get {
    // Get setting from storage or default
    if userStorage?.objectForKey("isDarkModeEnabled") == nil {
       userStorage?.setObject(false, forKey: "isDarkModeEnabled")
       userStorage?.synchronize()
    }

     return userStorage?.objectForKey("isDarkModeEnabled")
 }

 set {
    // Set new value in storage
    userStorage?.setObject(newValue, forKey: "isDarkModeEnabled")
    userStorage?.synchronize()
 }
}

在类的顶部,我声明了我的组容器ID并从中创建了NSUserDefault对象。然后,我的类属性具有getter和setter,用于将数据存储到App Group。如果密钥不存在,则使用默认值创建密钥并对其进行同步。从这一点开始使用这个类很简单:

var configModel = ConfigurationModel()
configModel.isDarkModeEnabled = true

此属性存储在云端!一切都被抽象出来给你。您不必为存储和同步到应用程序组而烦恼。这一切都是在吸气剂和制定者中自动完成的!

希望,这将有助于您了解如何在iPhone和Apple Watch应用之间共享数据。

答案 1 :(得分:1)

作为我研究和开发的一部分,我发现iPhone和Apple Watch的配对有可能是有用的。 在这种情况下,点击Watch应用程序上的按钮将在iPhone上发送文本。

要制作此功能的简单演示,请在WatchKit界面上放置一个按钮,并在iOS应用的故事板上放置一个标签。

现在,将按钮连接到WatchKit接口控制器作为IBAction,以响应按钮点击事件。还将Label作为IBOutlet连接到UI视图控制器。

在Interface Controller中,我们组成一个字符串变量以发送到标签,并在按钮的IBAction方法中,创建一个包含您所创建的字符串变量的字典。这个词典是传递给iPhone应用程序的。

class InterfaceController: WKInterfaceController {
    Var str: String = "Hello Phone"
    @IBAction func button() {
        let dict: Dictionary = ["message": str]
    }

使用以下方法将字典发送到iPhone。

WKInterfaceController.openParentApplication(dict, reply: {(reply, error) -> void in
     print("Reply receive from iPhone app")
})

在iOS应用的AppDelegate中,添加以下应用方法。这将是处理来自Watch的先前方法通信的内容。我们还可以使用通知来通知视图控制器已收到数据并将其传递。

func application(application: UIApplication, handleWatchkitExtensionRequest userInfo: [NSObject : AnyObject]?, reply:(([NSObject : AnyObject]!) {
    NSNotificationCenter.defaultCenter().postNotificationName("WatchKitReq", object: userInfo)
}

最后在视图控制器中,为通知创建一个监听器,该通知将标签的文本更新为随数据一起发送的字符串。

class ViewController: UIViewController {
        @IBOutlet weak var label: UILabel!
        override func viewDidLoad() {
          super.viewDidLoad()
          NSNotificationCenter.defaultCenter().addObserver(self, selector("handleWatchKitNotification:"), name: "WatchKitReq", object: nil)
}
func handleWatchKitNotification(notification: NSNotification) {
    if let userInfo = notification.object as? [String : String] {
        label.text = userInfo["message"]
    }
}

希望这会帮助你理解。有关更多问题,请查看此内容,

Delegate Method