PyObjus HealthKit support

85 views
Skip to first unread message

Michael

unread,
Jul 30, 2020, 7:42:42 AM7/30/20
to Kivy users support
Hi,

I am trying to make a Kivy app that uses data from HealthKit. The first step is to create a plyer api compatible with healthkit. I am using PyObjus to load the HealthKit.framework and then the autoclass function to load HKHealthStore(https://developer.apple.com/documentation/healthkit/hkhealthstore?language=objc). Once loaded, the only method I can get to successfully work is the isHealthDataAvailable method. All of the other methods fail.


Here is my healthkit.py platform code:
from pyobjus import autoclass, protocol
from pyobjus.dylib_manager import load_framework
from plyer.facades import HealthKitFacades
from pprint import pprint

load_framework
('/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/'+
               
'System/iOSSupport/System/Library/Frameworks/HealthKit.framework')
HKHealthStore = autoclass('HKHealthStore')


class IOSHealthKit(HealthKitFacades):
   
def __init__(self):
       
self._healthkit_manager = HKHealthStore
        pprint
(vars(HKHealthStore))


   
def _method_test(self, **kwargs):
       
try:
           
print(self._healthkit_manager.isHealthDataAvailable())
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.authorizationStatusForType)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.authorizationStatus)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.getRequestStatusForAuthorizationToShareTypes)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.HKAuthorizationRequestStatus)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.supportsHealthRecords)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.requestAuthorization)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.handleAuthorizationForExtension)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.bloodTypeWithError)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.biologicalSexWithError)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.executeQuery)
       
except Exception as e:
           
print(e)

       
try:
           
print(self._healthkit_manager.stopQuery)
       
except Exception as e:
           
print(e)


def instance():
   
'''
    Instance for facade proxy
    '''

   
return IOSHealthKit()

And here is the output after running _method_test:
True
'HKHealthStore' object has no attribute 'authorizationStatusForType'
'HKHealthStore' object has no attribute 'authorizationStatus'
'HKHealthStore' object has no attribute 'getRequestStatusForAuthorizationToShareTypes'
'HKHealthStore' object has no attribute 'HKAuthorizationRequestStatus'
'HKHealthStore' object has no attribute 'supportsHealthRecords'
'HKHealthStore' object has no attribute 'requestAuthorization'
'HKHealthStore' object has no attribute 'handleAuthorizationForExtension'
'HKHealthStore' object has no attribute 'bloodTypeWithError'
'HKHealthStore' object has no attribute 'biologicalSexWithError'
'HKHealthStore' object has no attribute 'executeQuery'
'HKHealthStore' object has no attribute 'stopQuery'

I have a feeling that this may be impossible to accomplish with Kivy/Pyobjus because of the complexity of the methods and their calls. Let me know what you think as to why the methods aren't working correctly.

Robert Flatt

unread,
Jul 30, 2020, 12:48:43 PM7/30/20
to Kivy users support
First check you build what you thought you built:


for e in dir( HKHealthStore):
   
print(e)

Second
'requestAuthorization'
If authorizion is involved there may be challenges ;)

Michael

unread,
Jul 30, 2020, 12:55:52 PM7/30/20
to Kivy users support
Right as you posted that I was in the process of doing it haha. Thank you for your help! Here is the output.

CA_CAMLPropertyForKey_
CA_automaticallyNotifiesObservers_
CA_encodesPropertyConditionally_type_
CA_getterForProperty_
CA_setterForProperty_
CKSQLiteClassName
SFSQLiteClassName
__accessibilityGuidedAccessRestrictionStateForIdentifier_
__accessibilityGuidedAccessStateEnabled
__accessibilityRequestGuidedAccessSession_completion_
__allocWithZone_OA_
__class__
__cls_storage
__copy_properties__
__delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__module__
__ne__
__new__
__objcclass__
__pyx_vtable__
__reduce__
__reduce_ex__
__repr__
__setattr__
__setstate__
__sizeof__
__str__
__subclasshook__
__weakref__
_accessibilityClearProcessedClasses_
_accessibilityHasUnitTestingOrientation
_accessibilityPerformValidations_
_accessibilitySetUnitTestingOrientation_
_accessibilityTextChecker
_accessibilityUndoAttributedDecisionCaching_
_accessibilityUnitTestingOrientation
_accessibilityUnsetUnitTestingOrientation
_accessibilityUpdateOpaqueFocusStateForTechnology_oldElement_newElement_
_addPropertyAttributeMapToPropertyMapLocked_
_copyDescription
_cplPropertyAttributeMap
_createMutableArrayValueGetterWithContainerClassID_key_
_createMutableOrderedSetValueGetterWithContainerClassID_key_
_createMutableSetValueGetterWithContainerClassID_key_
_createOtherValueGetterWithContainerClassID_key_
_createOtherValueSetterWithContainerClassID_key_
_createValueGetterWithContainerClassID_key_
_createValuePrimitiveGetterWithContainerClassID_key_
_createValuePrimitiveSetterWithContainerClassID_key_
_createValueSetterWithContainerClassID_key_
_installAppearanceSwizzlesForSetter_
_isDeallocating
_keysForValuesAffectingValueForKey_
_localClassNameForClass
_mapkit_instanceImplementationOfSelector_isFromSubclassOfClass_
_shouldAddObservationForwardersForKey_
_tryRetain
_webkit_invokeOnMainThread
accessInstanceVariablesDirectly
accessibilityBundles
accessibilityInitializeBundle
alloc
allocWithZone_
allowsWeakReference
automaticallyNotifiesObserversForKey_
autorelease
biologicalSex
brc_swizzleClassMethod_with_
brc_swizzleInstanceMethod_with_
bs_dataFromObject_
bs_decodedFromData_
bs_isPlistableType
bs_objectFromData_
bs_secureDataFromObject_
bs_secureDecodedFromData_
bs_secureDecodedFromData_withAdditionalClasses_
bs_secureObjectFromData_ofClass_
bs_secureObjectFromData_ofClasses_
cancelPreviousPerformRequestsWithTarget_
cancelPreviousPerformRequestsWithTarget_selector_object_
classFallbacksForKeyedArchiver
classForKeyedUnarchiver
classForStoredClassName_forCPLArchiver_
conformsToProtocol_
copy
copyWithZone_
cplAdditionalSecureClassesForProperty_
cplAllPropertyNames
cplDumpProperties
cplShouldIgnorePropertyForCoding_
cplShouldIgnorePropertyForEquality_
currentContextCanExecuteSelector_
dealloc
debugDescription
description
doesNotRecognizeSelector_
enc
fallback_debugHierarchyPropertyDescriptions
fallback_debugHierarchyValueForPropertyWithName_onObject_outOptions_outError_
forwardInvocation_
forwardingTargetForSelector_
fromPBCodable_
get_address
handleInvalidExecutionContextForSelector_requirement_
hash
implementingClassForInstanceMethod_
implementsClassMethod_
implementsInstanceMethod_
implementsSelector_
init
initialize
instanceMethodDescriptionForSelector_
instanceMethodForSelector_
instanceMethodSignatureForSelector_
instancesImplementSelector_
instancesRespondToSelector_
isAncestorOfObject_
isEqual_
isFault
isKeyExcludedFromWebScript_
isKindOfClass_
isMemberOfClass_
isProxy
isSelectorExcludedFromWebScript_
isSubclassOfClass_
keyPathsForValuesAffectingValueForKey_
load
methodDescriptionForSelector_
methodForSelector_
methodSignatureForSelector_
mf_clearLocks
mutableCopy
mutableCopyWithZone_
new
oclass
performSelector_
performSelector_withObject_
performSelector_withObject_withObject_
performSelector_withThreadKey_count_objects_
performSelector_withThreadKey_waitTime_cancelMask_count_objects_
release
replacementObjectForPortCoder_
resolveClassMethod_
resolveInstanceMethod_
respondsToSelector_
retain
retainCount
retainWeakReference
self
setExecutionContextCheckForAllClassMethods_
setExecutionContextCheckForAllInstanceMethods_
setExecutionContextCheck_forClassMethod_
setExecutionContextCheck_forInstanceMethod_
setKeys_triggerChangeNotificationsForDependentKey_
setVersion_
superclass
supportsBSXPCSecureCoding
supportsSecureCoding
upcase_first_letter
version
zone


Robert Flatt

unread,
Jul 30, 2020, 1:31:31 PM7/30/20
to Kivy users support
I dont see requestAuthorization

Presumably it didn't get built, try looking at that.

Authorization is a challenging issue, the source may not contain that code.....

Michael

unread,
Jul 30, 2020, 1:35:22 PM7/30/20
to Kivy users support
It is odd because the docs from Apple say that there should be more methods than what Pyobjus is outputting, such as...
- requestAuthorizationToShareTypes:readTypes:completion:
Requests permission to save and read the specified data types.


Michael

unread,
Jul 30, 2020, 2:01:04 PM7/30/20
to Kivy users support
Update:
When I run HKHealthStore.alloc().init(), I get a richer set of methods!
Output.rtf

Michael

unread,
Aug 1, 2020, 7:43:59 AM8/1/20
to Kivy users support
If anyone is interested, I will keep posting my progress here with the conclusion hopefully being a pull request. I am going to work on this for a couple of days more, and I am getting less hopefully that kivy/pyobjus will be able to do the job.

Right now I am stuck on the Authorization step(https://developer.apple.com/documentation/healthkit/authorizing_access_to_health_data?language=objc). I have posted all of the methods of each class in rtf format. If y'all have any ideas... plz I need help.

HKHealthStore_alloc.rtf
HKObject.rtf
HKObjectType.rtf
HKQuantityTypeIdentifier.rtf
HKSeriesType.rtf
NSError.rtf
Reply all
Reply to author
Forward
0 new messages