0

I am trying to build a MVP with SwiftUI that simply shows me the changes in altitude on my Apple Watch. From there I will figure out where to go next (I want to use it for paragliding and other aviation things).

I have previous experience in python, but nothing in Swift, so even after a ton of tutorials I am very unsure about how and where to declare and then use functionalities.

Here is my code so far:

//
//  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()
    }
}

I am getting multiple errors that I dont know how to deal with:

  • Type 'Void' cannot conform to 'View', only struct/enum/class types can conform to protocols.
  • Value of type CMMotionManager has no member 'isRelativeAltitudeAvailable'
  • Type '()' cannot conform to View...
  • Cannot convert value of type 'CMAltitudeHandler.Type' (aka '((Optional, Optional) -> ()).Type') to expected argument type 'CMAltitudeHandler' (aka '(Optional, Optional) -> ()')

Could you please give me some hints?

Thank you so much! Luke

Luke Crouch
  • 107
  • 6

1 Answers1

1

I figured it out after trying around a lot:

//
//  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()
    }
    
}

Next steps will be to check if I can access the barometer raw data and calculate altitudes on that.

Luke Crouch
  • 107
  • 6
  • It seems that the `CMAltimer` is using the iPhone sensor and not the watch sensor to measure altitude. Were you able to get the output of the watch sensor? – RawMean Oct 13 '21 at 02:28
  • Im using CMAltimeter in my watch app as well as the phone app and both work independently from each other. Why do you think that? – Luke Crouch Oct 19 '21 at 10:42
  • Specifically, the relativeAltitude value comes from the iPhone even though the code is being executed on the watch. The absolute altitude comes from the watch. To test it, go upstairs with the watch but leave the iPhone downstairs and observe that relative altitude does not change. – RawMean Oct 19 '21 at 16:19