omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    HomeKit

    Pythonista
    3
    16
    9201
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jm2466
      jm2466 last edited by

      This is the first time I am trying objc_util so not sure if I am doing something wrong. I am trying to access my HomeKit setup and am starting with the following

      from objc_util import *
      load_framework('HomeKit')
      HMHomeManager = ObjCClass('HMHomeManager')
      homemanager = HMHomeManager.alloc().init()

      This is based on the objective c call:
      self.homeManager = [[HMHomeManager alloc] init];

      My code crashes Pythonista but removing init() does not. I am sure someone will say "then just remove it" but it appears in looking at other objc_util examples that it is expected to be called. Running without init does let me get the primary home but no rooms - the big "but" is I have not coded the delegate methods which appears to be useful.

      Anyhow at this point was wondering if anyone has done anything with HomeKit that they could share. Also wondering about the init() issue.

      Thanks

      1 Reply Last reply Reply Quote 0
      • mikael
        mikael last edited by

        Not working with HomeKit yet, but always a good idea to enable @dgelessus’ faulthandler - you see what the ObjC exception was that caused the crash, and might get some idea how to fix it.

        Also, did you share a full ”working” example? Are you sure it crashes on the init line?

        1 Reply Last reply Reply Quote 0
        • jm2466
          jm2466 last edited by

          Thanks for the reply, will take a look at the fault handler.

          My code is pretty much all I have at this point (I had a few lines after to get room info but commented that out to track down the crash). In the code I posted it will crash with init and not when it is removed - not the entire line just removing .init()

          1 Reply Last reply Reply Quote 0
          • jm2466
            jm2466 last edited by jm2466

            So I tried to add the delegate and added the fault handler. With the init removed it crashes when assigning the delegate.

            Here is my code:

            from __future__ import absolute_import, division, print_function
            from objc_util import *
            from pythonista_startup.enable_faulthandler import run
            
            load_framework('HomeKit')
            
            def homeManagerDidUpdateHomes(self, cmd):
            	print('homeManagerDidUpdateHomes')
            
            methods = [homeManagerDidUpdateHomes]
            protocols = ['HMHomeManagerDelegate']
            MyHMHomeManagerDelegate = create_objc_class('MyHMHomeManagerDelegate',NSObject,methods=methods,protocols=protocols)
            
            def main():
            	print('Start of script')
            	# run enable faulthandler
            	run()
            	myHMHomeManagerDelegate = MyHMHomeManagerDelegate.alloc()
            	HMHomeManager = ObjCClass('HMHomeManager')
            	homemanager = HMHomeManager.alloc()
            	homemanager.setDelegate(myHMHomeManagerDelegate)
            	print('End of script')
            
            if __name__ == '__main__':
            	main()
            

            NOTE: The objc delegate method is:

            - (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager;
            

            When I tried to define the python delegate method as def homeManagerDidUpdateHomes(self, cmd,manager): I got an error that the method was only expecting 2 parameters but found 3.

            Back to the code... as mentioned I first ran with the line to set the delegate which crashed so I then commented out the set delegate line to let it complete successfully. The fault handler outputted the following:

            Start of script
            Enabling fault handler and Objective-C exception handler...
            Pythonista quit abnormally last time.
            For details, see the following log file: faultlog-2018-02-19-14-36-24.txt
            Setting fault handler.
            Done enabling fault handler and Objective-C exception handler.
            End of script

            The contents of the fault log

            Fatal Python error: Segmentation fault

            Current thread 0x000000016f72b000 (most recent call first):
            File "/var/containers/Bundle/Application/31989ED7-8359-46ED-90D1-AA84E7A73FA8/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 897 in call
            File "/var/containers/Bundle/Application/31989ED7-8359-46ED-90D1-AA84E7A73FA8/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 803 in call
            File "/private/var/mobile/Containers/Shared/AppGroup/0ED4DCFF-B233-4C51-A9EF-89FAA67A9C87/Pythonista3/Documents/Test01/HomeKit03.py", line 21 in main
            File "/private/var/mobile/Containers/Shared/AppGroup/0ED4DCFF-B233-4C51-A9EF-89FAA67A9C87/Pythonista3/Documents/Test01/HomeKit03.py", line 25 in <module>

            Here is the fault log when using alloc().init()

            Fatal Python error: Aborted

            Thread 0x000000016b577000 (most recent call first):

            I also tried .delegate = instead of setDelegate which crashed with the following log

            Fatal Python error: Segmentation fault

            Current thread 0x000000016f8a3000 (most recent call first):
            File "/var/containers/Bundle/Application/31989ED7-8359-46ED-90D1-AA84E7A73FA8/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 897 in call
            File "/var/containers/Bundle/Application/31989ED7-8359-46ED-90D1-AA84E7A73FA8/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 650 in setattr
            File "/private/var/mobile/Containers/Shared/AppGroup/0ED4DCFF-B233-4C51-A9EF-89FAA67A9C87/Pythonista3/Documents/Test01/HomeKit03.py", line 22 in main
            File "/private/var/mobile/Containers/Shared/AppGroup/0ED4DCFF-B233-4C51-A9EF-89FAA67A9C87/Pythonista3/Documents/Test01/HomeKit03.py", line 26 in <module>

            Thanks for the help.

            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by JonB

              I suspect your issue is that the delegate and maybe the manager gets destroyed at the end of main(). retain, or return them and retain them in the callers scope.

              from __future__ import absolute_import, division, print_function
              from objc_util import *
              from pythonista_startup.enable_faulthandler import run
              
              load_framework('HomeKit')
              
              def homeManagerDidUpdateHomes_(self,sel,manager):
                 print(ObjCInstance(self))
                 print('homeManagerDidUpdateHomes')
              
              methods = [homeManagerDidUpdateHomes_]
              protocols = ['HMHomeManagerDelegate']
              MyHMHomeManagerDelegate = create_objc_class('MyHMHomeManagerDelegate',NSObject,methods=methods,protocols=protocols)
              
              def main():
                  print('Start of script')
                  # run enable faulthandler
                  run()
                  #every alloc must have an init, or initWith...
                  #, or can use .new() instead of .alloc().init()
                  myHMHomeManagerDelegate = MyHMHomeManagerDelegate.alloc().init()
                  HMHomeManager = ObjCClass('HMHomeManager')
                  homemanager = HMHomeManager.alloc().init()
                  homemanager.setDelegate(myHMHomeManagerDelegate)
                  
                  # homemanager and delegate must be retained, or returned, 
                  # otherwise python object gets destroyed 
                  
                  return homemanager,myHMHomeManagerDelegate
                  #alternatively
                  #retain_global(myHMHomeManagerDelegate)
                  #retain_global(homemanager)
                  print('End of script')
              
              if __name__ == '__main__':
                 homemanager,myHMHomeManagerDelegate = main()
              

              i dont have anything to test with, but this doesnt crash, and you can call the delegate manually...

              edit: also, i think the proper delegate method is
              homeManagerDidUpdateHomes_manager_
              which takes homes, and manager args.
              edit: nope.. the original was right
              edit again... homeManagerDidUpdateHomes_
              you were missing the underscore. You have to replace colons with underscore for methods that take arguments. This did get called automatically

              1 Reply Last reply Reply Quote 0
              • jm2466
                jm2466 last edited by

                Thanks for looking into this and the reply. I pasted your code into a new script file and unfortunately it is crashing pythonista at the alloc init again. If I take off the init it crashes when setting the delegate as before. I am using a different iOS device than yesterday but I appear to be having the same issue. I am running iOS 11.2.5 on the device I am trying it on now if that matters.

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  Which init is crashing? The delegate or the manager?
                  You can't skip init, you don't really have an objc object until you run init. Alternatively, try new() instead of alloc ().init().

                  Did you get a pop-up allowing homekit access? Check settings app. I think homekit requires an entitlement but don't know whether that was always enforced, or if pythonista has that entitlement. I'm on a os9.4 device.

                  1 Reply Last reply Reply Quote 0
                  • jm2466
                    jm2466 last edited by

                    The delegate is created first and the init on it causes a crash. If I comment that line or remove the init then the HMHomeManager causes the crash with the init. Also tried new() with the same result.

                    I did not get a popup asking for HomeKit access. I just checked in Xcode and HomeKit is a capability that needs turned on for the app (pythonista in this case as you mention). Ultimately it has to be set on the app id (Xcode will do this or can be done in the developer portal for the app id).

                    Will send a support email asking about this.

                    Thanks

                    1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB last edited by

                      I'm not sure which version of iOS started enforcing the entitlement. Again, it works for me. Creating the delegate should not require the entitlement, since it does jnot do anything. Try creating just the delegate, and using alloc().init(). Then try again without specifying the protocol. If that still crashes, try without the method.

                      Can you also try one of the objc examples that use a custom delegate class? Just to ensure objc_util is really working...

                      1 Reply Last reply Reply Quote 0
                      • JonB
                        JonB last edited by

                        Oh, also use the debug=True flag in your create_objc_class. Your code could fail because the class name might not be unique. Not sure.

                        JonB 1 Reply Last reply Reply Quote 0
                        • JonB
                          JonB @JonB last edited by

                          Also, I'm on the beta, which might have different entitlements... @omz?

                          1 Reply Last reply Reply Quote 0
                          • jm2466
                            jm2466 last edited by

                            I tried a different sample app that uses alloc init and delegates and it works. Heard back from Ole and Pythonista is not a HomeKit app and it does appear it will become one. I am guessing that is why it is crashing. Thanks for the help.

                            My use case is to provide a different UI and organization for HomeKit triggers based on how I am using it. I know how to develop apps in Swift and could go that route but I believe the free developer account apps are only signed for 7 days. This will not be a frequently used app and I could go that route (having to deploy it from Xcode each time I need to run it after 7 days from last run). Pythonista would have filled the need perfectly if it was HomeKit capable.

                            1 Reply Last reply Reply Quote 0
                            • JonB
                              JonB last edited by

                              i would have expected entitlement problems to show up in faulthandler as such. also, i cannot believe you need an entitlement to create a custom delegate class.

                              Id like to suggest a custom settrace() so we can find exactly where the crash occurs (it probably is in the objc_util call somewhere, but it would be interesting to see exactly which line. I think you said your were getting segfault, which sounds like a different problem.

                              mikael 1 Reply Last reply Reply Quote 0
                              • mikael
                                mikael @JonB last edited by

                                @JonB, do you think there is still a solution to be found, even if Pythonista app is not HomeKit-enabled?

                                1 Reply Last reply Reply Quote 0
                                • JonB
                                  JonB last edited by

                                  It is not obvious that the entitlement is the problem -- also, I am not sure it is enforced on app, versus just in Xcode, since the example works for me. Maybe it is enforced in later ios versions, or not enforced on the testflight version... do you get the same crash mikael?

                                  mikael 1 Reply Last reply Reply Quote 0
                                  • mikael
                                    mikael @JonB last edited by

                                    @JonB, I am on 11.2.6 and get a crash with ”Fatal Python error: Aborted” at HomeManager init, delegate init is fine.

                                    1 Reply Last reply Reply Quote 0
                                    • First post
                                      Last post
                                    Powered by NodeBB Forums | Contributors