• The difference is that things like CGRect and the like are structures, not full fledged objects. CGRectMake is not a real function, but an inlined function that gets optimized away by the obj compiler, and so there is nothing to call.

    You either have to find someone who has done the work and converted the library to python ctypes lib that you can import, or else do it yourself. Rubicon is a good place to look for much of the the core stuff

  • @JonB yeah, changing c_void_p to c_byte still results in a crash with the same fault log, and setting the handler to None also results in a crash with the same fault log.

  • You may be interested in my objc viewbrowser:

    You can present your view, then traverse the heirarchy to see all of the UIViews. Tapping an item highlights it onscreen.
    Also, any action/targets are shown as little chain icons, which you can tap and it prints to the console the details on the target, selector, event codes, etc. Tapping the info button shows all of the objc properties, which is also navigatable.

  • The use case is a little complicated, and very task-specific:

    app is constantly listening for incoming messages manipulating controls in the view sends outgoing messages some incoming messages will try to set the value of a control being manipulated this leads to "fighting" between the user and the system knowing which control or controls are being interacted with, we can filter the incoming messages so they don't attempt to set controls actively being manipulated, effectively "debouncing" the signal

    I like the idea of a transparent layer...but I wanted to be more specific about what I considered "manipulating" the control...with this, I can say exactly what I consider to be user interaction for these purposes.

    Anyway, I am using the sender argument coming from the addTarget_action_forControlEvents() call, which is how I'm keying which controls are marked active. For my purposes it is working.Unfortunately, it seems like the various Pythonista-wrapped UIControls have different ways, or sometimes no way, of getting access to the actual UIControl instance they wrap, which makes it a little complicated to call the addTarget_ objectiveC method to install the monitor.

  • Hey thank you everyone.

    I must have had a typo when I initially posted this - but it seems to work now.

    Notes: I used ui.parse_color('blue').CGColor()

    This works with RGBA, Hex and Named Colors.

    Ill post the code when done, I am using this to create custom button styles, along with some custom styles for "checkbox" functionality (circles, squares, stars, etc)

    Thanks again for your help!

  • @mikael faulthandler seems really useful, Thanks!

  • Or, to look at it in another way, you are resizing the contained Stepper, but not the containing View.

  • @cbanta, what is the exception? Install the fault handler to find out.

  • @JonB It's when I read such posts that I recognize that I really don't know anything about Objective-C 😢

  • Thank you!!!!

  • @dgelessus : you're right ! I've extracted objc_util.py from my current Pythonista and have copied it to the XCode Template project (PythonistaAppTemplate/PythonistaKit.framework/pylib/site-packages directory ). Now, I can test my app :o)

    @JonB : I don't need to add the framework I want to load in my xcode project. I've removed the framework in the xcode project and my app can be launched without any problem...Perhaps as it's an Apple framework, I don't need to add it....My xcode knowledge is a little low ;o)

    Thank you for your help...

  • Hi,
    Finally, I managed to initialize an ar session
    but I remain open to any improvement (
    especially the famous ARKit constants and the call to the sleep function ;o)

    Here the code :

    # coding: utf-8 import objc_util from objc_util import * import ui import os import sys #from myDebugToolKit import * import time from enum import IntFlag load_framework('SceneKit') load_framework('ARKit') # Some 'constants' used by ARkit # But i can't transfer them to the ARKit framework, why ????? class ARWorldAlignment(IntFlag): ARWorldAlignmentGravity = 0 ARWorldAlignmentGravityAndHeading = 1 ARWorldAlignmentCamera = 2 class ARPlaneDetection(IntFlag): ARPlaneDetectionNone = 0 ARPlaneDetectionHorizontal = 1 << 0 ARPlaneDetectionVertical = 1 << 1 # Work In Progress here, I'm deciphering the ARKit constants... #class ARSCNDebugOption(IntFlag): # ARSCNDebugOptionNone = 0 # ARSCNDebugOptionShowWorldOrigin = int("ffffffff80000000", 16) # ARSCNDebugOptionShowFeaturePoints = int("ffffffff40000000", 16) class ARSessionRunOptions(IntFlag): ARSessionRunOptionsNone = 0 ARSessionRunOptionResetTracking = 1 << 0 ARSessionRunOptionRemoveExistingAnchors = 1 << 1 NSError = ObjCClass('NSError') SCNScene = ObjCClass('SCNScene') ARSCNView = ObjCClass('ARSCNView') ARWorldTrackingConfiguration = ObjCClass('ARWorldTrackingConfiguration') ARSession = ObjCClass('ARSession') UIViewController = ObjCClass('UIViewController') ARPlaneAnchor = ObjCClass('ARPlaneAnchor') # I should refactor te following line in a class but I need to learn more the create_objcc_class function sceneview = None # Here some set up functions used by the main class def createSampleScene(): # an empty scene scene = SCNScene.scene() return scene def setDebugOptions(arscn): # Work In Progress Here, I'm trying to decipher the arkit constants... #val = ARSCNDebugOption.ARSCNDebugOptionShowWorldOrigin | ARSCNDebugOption.ARSCNDebugOptionShowFeaturePoints val = int("fffffffffc000000", 16) # this value is a combination of ShowWorldOrigin and ShowFeaturePoints flags, but I can't isolate each flags.... print('Before calling setDebugOptions_(%s) : debugOptions=%s' %(hex(val), hex(arscn.debugOptions()))) arscn.setDebugOptions_(val) print('After calling setDebugOptions_(%s) : debugOptions=%s' % (hex(val),hex(arscn.debugOptions()))) def createARSceneView(x, y, w, h, debug=True): v = ARSCNView.alloc().initWithFrame_((CGRect(CGPoint(x, y), CGSize(w, h)))) v.setShowsStatistics_(debug) # I love statistics... return v # Some callback definitions used by create_objc_class def CustomViewController_touchesBegan_withEvent_(_self, _cmd, _touches, event): touches = ObjCInstance(_touches) for t in touches: loc = t.locationInView_(sceneview) sz = ui.get_screen_size() print(loc) @on_main_thread def runARSession(arsession): arconfiguration = ARWorldTrackingConfiguration.alloc().init() arconfiguration.setPlaneDetection_ (ARPlaneDetection.ARPlaneDetectionHorizontal) arconfiguration.setWorldAlignment_(ARWorldAlignment.ARWorldAlignmentGravity) # I do not use ARWorldAlignmentGravityAndHeading anymore because on my device, sometimes it fails to initialize the ar session because of an unitialized sensor (error 102). I think my magnetic phone casing plays tricks on me... arsession.runWithConfiguration_options_(arconfiguration, ARSessionRunOptions.ARSessionRunOptionResetTracking | ARSessionRunOptions.ARSessionRunOptionRemoveExistingAnchors ) time.sleep(0.5) # Let the system breathe ;o) Ok, that's the workarround I found to retrieve the ar session configuration (otherwise I got None).... print('configuration',arsession.configuration()) # Very usefull for the debuging (at least for me !) def CustomViewController_viewWillAppear_(_self, _cmd, animated): return def CustomViewController_viewWillDisappear_(_self, _cmd, animated): session = sceneview.session() session.pause() def MyARSCNViewDelegate_renderer_didAdd_for_(_self, _cmd, scenerenderer, node, anchor): if not isinstance(anchor, (ARPlaneAnchor)): return # to be implemented... def MyARSCNViewDelegate_session_didFailWithError_(_self,_cmd,_session,_error): print('error',_error,_cmd,_session) err_obj=ObjCInstance(_error) print(err_obj) # Again, very usefull for the debuging... # The main class... class MyARView(ui.View): def __init__(self): super().__init__(self) @on_main_thread def initialize(self): global sceneview self.flex = 'WH' screen = ui.get_screen_size() # set up the scene scene = createSampleScene() # set up the ar scene view delegate methods = [MyARSCNViewDelegate_renderer_didAdd_for_,MyARSCNViewDelegate_session_didFailWithError_] protocols = ['ARSCNViewDelegate'] MyARSCNViewDelegate = create_objc_class('MyARSCNViewDelegate', NSObject, methods=methods, protocols=protocols) delegate = MyARSCNViewDelegate.alloc().init() # set up the ar scene view sceneview = createARSceneView(0, 0, screen.width, screen.height) sceneview.scene = scene sceneview.setDelegate_(delegate) # set up the custom view controller methods = [CustomViewController_touchesBegan_withEvent_, CustomViewController_viewWillAppear_, CustomViewController_viewWillDisappear_] protocols = [] CustomViewController = create_objc_class('CustomViewController', UIViewController, methods=methods, protocols=protocols) cvc = CustomViewController.alloc().init() cvc.view = sceneview # internal scheming... self_objc = ObjCInstance(self) self_objc.nextResponder().addChildViewController_(cvc) self_objc.addSubview_(sceneview) cvc.didMoveToParentViewController_(self_objc) # here, we try... runARSession(sceneview.session()) # I call here this function because I'm trying to find the best place to run the ar session... setDebugOptions(sceneview) # I call here this function because I'm trying to find the best place to set the debuging options.... def will_close(self): session = sceneview.session() session.pause() if __name__ == '__main__': v = MyARView() v.present('full_screen', hide_title_bar=True, orientations=['portrait']) v.initialize()

    Note: if someone can correct the autorotate, I'm also interested !o)
    Edit: I found a solution for my autorotate problem -> I turn it off ;o)

    Live session

  • @dgelessus said:

    Ah, that's an auto-generated header from a class dump or something like that. I was looking at the "real" headers from the iOS SDK, which use vector types. (The iOS SDK headers aren't available online, the closest thing you can see is Apple's online documentation for GKAgent2D.position.) I'm guessing that during compilation some "magic" happens to properties/methods that use vector types, and the result is what you see in the class dump header. You could try using the methods position_ and setPosition__ (note the extra underscores), which according to the class dump header use structs instead of vector types.

    Thank you very much, using the methods with underscore solved the problem!

  • @omz said:

    I can't test this right now, but I have a suspicion that you need to set the argtypes and restype properties of the ObjC method manually. The derivation from the protocols argument doesn't always work reliably if the protocol isn't used as part of Pythonista itself. I hope this makes sense.

    I completely forgot about argtypes and restype honestly. It makes sense, I will keep trying to find out correct argtypes. Thanks for your suggestion. Please let me know once you test.

  • Thanks for those suggestions, learning about threading was very helpful.

    Apparently, the while loop was working the whole time! I feel very silly now. It didn't appear to be working because it always updated the decibel level to be -120 (which is unusual because -160 is typically silence). It is my hypothesis that Apple restricts widgets in certain ways like recording (which is odd because I've used taptic feedback in a widget before). (Ex: the Shazam app has a widget, but it has to open the app to work.) Anyway, my new problem will be figuring out if it's possible to collect and analyze the recording elsewhere and pass that information to the widget through some sort of callback url.

  • Thanks :)

  • Something like this should work:

    err_ptr = c_void_p() device_input = ObjCClass('AVCaptureDeviceInput').deviceInputWithDevice_error_(input_device, byref(err_ptr)) if err_ptr: err = ObjCInstance(err) print(err)
  • Thanks my dude ;)

  • Nice! Very Interesting

Internal error.

Oops! Looks like something went wrong!