使用 SwiftUi 为 Apple Watch 构建一个基本的高度计

Posted

技术标签:

【中文标题】使用 SwiftUi 为 Apple Watch 构建一个基本的高度计【英文标题】:Build a basic Altimeter with SwiftUi for Apple Watch 【发布时间】:2020-10-07 08:07:25 【问题描述】:

我正在尝试使用 SwiftUI 构建一个 MVP,它只是向我显示 Apple Watch 上的高度变化。从那里我会弄清楚下一步要去哪里(我想用它来滑翔伞和其他航空用品)。

我以前在 python 方面有经验,但在 Swift 方面一无所知,所以即使经过大量教程后,我也不确定如何以及在何处声明和使用功能。

到目前为止,这是我的代码:

//
//  ContentView.swift
//  Altimeter WatchKit Extension
//
//  Created by Luke Crouch on 29.09.20.
//

import SwiftUI
import CoreMotion


//class func isRelativeAltitudeAvailable() -> Bool


struct ContentView: View 
    let motionManager = CMMotionManager()
    let queue = OperationQueue()
    let altimeter = CMAltimeter()
    let altitude = 0
    var relativeAltitude: NSNumber = 0
    
    var body: some View 
        
        if motionManager.isRelativeAltitudeAvailable() 
         switch CMAltimeter.authorizationStatus() 
         case .notDetermined: // Handle state before user prompt
             fatalError("Awaiting user prompt...")
         case .restricted: // Handle system-wide restriction
            fatalError("Authorization restricted!")
         case .denied: // Handle user denied state
            fatalError("Auhtorization denied!")
         case .authorized: // Ready to go!
             print("Authorized!")
         @unknown default:
            fatalError("Unknown Authorization Status")
         
            altimeter.startRelativeAltitudeUpdates(to: queue, withHandler: CMAltitudeHandler)
        

// something like relative Altitude = queue[..]
        
        Text("\(relativeAltitude)")
            .font(.largeTitle)
            .fontWeight(.bold)
            .foregroundColor(Color.green)
    



struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

我遇到了多个我不知道如何处理的错误:

类型“Void”不能符合“视图”,只有结构/枚举/类类型可以符合协议。 CMMotionManager 类型的值没有成员“isRelativeAltitudeAvailable” 类型“()”不能符合视图... 无法将类型“CMAltitudeHandler.Type”(又名“((可选,可选)->()).Type”)的值转换为预期的参数类型“CMAltitudeHandler”(又名“(可选,可选)->() ')

你能给我一些提示吗?

非常感谢! 卢克

【问题讨论】:

您提到您遇到多个错误,您应该在问题中包含这些错误。 你说得对,我编辑了我的问题! 【参考方案1】:

我试了很多次才明白:

//
//  ContentView.swift
//  Altimeter WatchKit Extension
//
//  Created by Lukas Wheldon on 29.09.20.
//

import SwiftUI
import CoreMotion

struct ContentView: View 
    @State var relativeAltitude: NSNumber = 0
    @State var altitude = 0
    let altimeter = CMAltimeter()
    
    func update(d: CMAltitudeData?, e: Error?)
        print("altitude \(altitude)")
        print("CMAltimeter \(altimeter)")
        print("relative Altitude \(relativeAltitude))")
        
    
    
    
    var body: some View 
        VStack 
            Text("\(altimeter)")
                .fontWeight(.bold)
                .foregroundColor(Color.green)
            Button(action: 
                print("START")
                self.startAltimeter()
            , label: 
                Text("Start Altimeter")
                    .bold()
                    .foregroundColor(.green)
            )
        
    
    
    func startAltimeter() 
        if CMAltimeter.isRelativeAltitudeAvailable() 
            switch CMAltimeter.authorizationStatus() 
             case .notDetermined: // Handle state before user prompt
             print("bb")
             //fatalError("Awaiting user prompt...")
             case .restricted: // Handle system-wide restriction
             fatalError("Authorization restricted!")
             case .denied: // Handle user denied state
             fatalError("Authorization denied!")
             case .authorized: // Ready to go!
             let _ = print("Authorized!")
             @unknown default:
             fatalError("Unknown Authorization Status")
             
            self.altimeter.startRelativeAltitudeUpdates(to: OperationQueue.main) (data,error) in DispatchQueue.main.async 
                print("\(altitude)")
                print("\(relativeAltitude)")
            
            
            
        
    
    




struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    
    

接下来的步骤将是检查我是否可以访问气压计原始数据并计算海拔高度。

【讨论】:

CMAltimer 似乎使用 iPhone 传感器而不是手表传感器来测量高度。你能得到手表传感器的输出吗? 我在我的手表应用程序和手机应用程序中使用 CMAltmeter,并且两者都相互独立工作。你为什么这么认为? 具体来说,relativeAltitude 值来自 iPhone,即使代码是在手表上执行的。绝对高度来自手表。要测试它,请带着手表上楼,但将 iPhone 留在楼下,观察相对高度没有变化。

以上是关于使用 SwiftUi 为 Apple Watch 构建一个基本的高度计的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中使用 WCSession 向 Apple Watch 发送消息

Apple Watch 模态表中的 SwiftUI 图像

Swiftui - Apple Watch 上的金属渲染

带有 SwiftUI 的 Apple Watch 上列表项的背景 [重复]

Apple Watch SwiftUI 地图事件?如何读取数字表冠旋转的当前区域跨度?

SwiftUI .rotation3dEffect 动画在 Apple Watch 列表行中没有所需的深度效果