B4i Library [class] Altimeter

The attached project includes the Altimeter class. It allows tracking altitude changes based on air pressure changes.

Note that it depends on the iPhone library.

The changes are incremental. It depends on iOS 8+. Only iPhone 6 and above support this feature.
 

Attachments

  • Altimeter.zip
    1.8 KB · Views: 57

Tonrad

Member
Licensed User
Hello everyone.
This method of working with the pressure sensor does not work in iOS 17.
Are there alternative ways to get pressure from the iOS barosensor?
 

Tonrad

Member
Licensed User
Error occurs at line End Sub of Application_Start in Main.
But the error disappears if i disable the line no.RunMethod("startNative:", Array(alt)) in Altimeter module.
But when this line is disabled, naturally nothing works.

Error message:
Application_Start
Error occurred on line: 40 (Main)
*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
Stack Trace: (
  CoreFoundation       7A70D5D4-0550-38DC-AB33-71B72AFF1F5F + 969524
  libobjc.A.dylib      objc_exception_throw + 60
  CoreFoundation       7A70D5D4-0550-38DC-AB33-71B72AFF1F5F + 100324
  CoreFoundation       7A70D5D4-0550-38DC-AB33-71B72AFF1F5F + 32028
  B4i Example          __29-[b4i_altimeter startNative:]_block_invoke_2 + 172
  libdispatch.dylib    7835E829-0652-3CB5-99D8-2CE521476DC0 + 8508
  libdispatch.dylib    7835E829-0652-3CB5-99D8-2CE521476DC0 + 15828
  libdispatch.dylib    7835E829-0652-3CB5-99D8-2CE521476DC0 + 75172
  libdispatch.dylib    _dispatch_main_queue_callback_4CF + 44
  CoreFoundation       7A70D5D4-0550-38DC-AB33-71B72AFF1F5F + 226588
 CoreFoundation       7A70D5D4-0550-38DC-AB33-71B72AFF1F5F + 213528
 CoreFoundation       CFRunLoopRunSpecific + 608
 GraphicsServices     GSEventRunModal + 164
 UIKitCore            86B7C8DD-E910-31BD-B8FE-28962256DEE3 + 2272988
 UIKitCore            UIApplicationMain + 340
 B4i Example          main + 100
 dyld                 960A7452-3178-3C9D-8CE5-FE40FDE8DBC8 + 23940
)
SignalHandler 6

Error line (17):
Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.LoadLayout("1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)

    alt.Initialize(Me, "alt")
    
    If alt.Supported Then
        alt.Start
    Else
        Log("Not supported")
    End If
    
End Sub     ' !!! ERROR OCCURS AT THIS LINE !!!

Private Sub alt_Update (AltitudeChange As Float, Pressure As Float)
    Log($"Altitude change in meters: $1.3{AltitudeChange}"$)
    Log($"Pressure in kilopascals: ${Pressure}"$)
    
    Label1.Text = "Pressure in hPa: " & NumberFormat2(Pressure*10, 3, 2, 2, False )
    Label2.Text = $"Altitude change in meters: $1.3{AltitudeChange}"$
End Sub

The reason for the error in Altimeter module:
Public Sub Start
    Dim no As NativeObject = Me
    no.RunMethod("startNative:", Array(alt))   'The error disappears if this line is disabled. But then nothing works.
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've updated the code and it is still not working. Might be a bug in iOS 17.4: https://forums.developer.apple.com/forums/thread/747797

This is the updated code:
B4X:
#Event: Update (AltitudeChange As Float, Pressure As Float)
Sub Class_Globals
    Private mCallback As Object
    Private mEventName As String    
    Private alt As NativeObject
    Private isSupported As Boolean
    Public AUTH_NOT_DETERMINED = 0, AUTH_RESTRICTED = 1, AUTH_DENIED = 2, AUTH_AUTHORIZED = 3 As Int
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
    mCallback = Callback
    mEventName = EventName
    alt.Initialize("CMAltimeter")
    isSupported = alt.RunMethod("isRelativeAltitudeAvailable", Null).AsBoolean
    If isSupported Then
        alt = alt.RunMethod("new", Null)
    End If
End Sub

Public Sub getAuthorizationStatus As Int
    Dim no As NativeObject
    Return no.Initialize("CMAltimeter").GetField("authorizationStatus").AsNumber
End Sub

Public Sub getSupported As Boolean
    Return isSupported
End Sub

Public Sub Start
    Dim no As NativeObject = Me
    no.RunMethod("startNative:", Array(alt))
End Sub

Private Sub Event_Handler(altitude As Float, pressure As Float)
    CallSub3(mCallback, mEventName & "_update", altitude, pressure)
End Sub
#if OBJC
- (void) startNative:(CMAltimeter*)alt {
     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [alt startRelativeAltitudeUpdatesToQueue:queue withHandler:^(CMAltitudeData *altitudeData, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^ {
            if (error != nil) {
                NSLog(@"Altimeter error: %@", error);
            } else {
                [self.bi raiseEvent:nil event:@"event_handler::" params:@[altitudeData.relativeAltitude, altitudeData.pressure]];
            }

        });
    }];
}
#end if

And you need to add this to main module:
B4X:
#PlistExtra: <key>NSMotionUsageDescription</key><string>show altimeter changes</string>

It should ask for permission but doesn't.
 

Tonrad

Member
Licensed User
Thank you for your support, Erel.
The problem is solved in iOS 17.5

iOS & iPadOS 17.5 Beta Release Notes​

...​

Core Motion

New Features

  • To respect users’ privacy, apps calling CMAltimeter’s startRelativeAltitudeUpdatesToQueue and stopRelativeAltitudeUpdates are now required to include the NSMotionUsageDescription string in their plist in order to receive data.
    Apps built with SDKs prior to iOS 17.5 and watchOS 10.5 without the NSMotionUsageDescription string in their plists will not receive data.
    Apps built with iOS 17.5 and watchOS 10.5 or later will crash if they do not have the NSMotionUsageDescription string in their plist as described in CMAltimeter. (125573971)
 
Top