• @mikael that is really odd...on my iPad Air it happens every time I run/end/run-again. On my iPhone 7, it does not.
    Setting "retain_global_reference" to True or False appears not to make a difference, I guess since I'm holding a reference to the Gestures instance in my View instance.

    I would love to know if @JonB or anyone else can reproduce this? Seems strange it would only be my iPad that sees the issue.

    Regardless, simply importing objc_util inside simplify() fixed it for me, so I'm ok with a tiny change like that. The module is fantastic @mikael.

  • @JonB Thanks

  • Hi @reticulated, I'm quite sure omz is still working on Pythonista because I think it's tremendous (and not very smart) that such an application is abandoned. We should know that he knows this fact (I know he knows this fact).

    I'm happy when people help people with ideas, codes, examples, informations.
    You are talking about things too advanced for me, but I'm sure you are talking in order to give Pythonista more power.

    The nice and curious thing is to understand how to give more power to Pythonista without pretending that is omz to give it (that is without need to compile entire Pythonista for new releases).

    The best thing in my opinion is to give omz maximum freedom to decide when to give us new releases of his great app, and in the meantime people could continue to give more power to Pythonista, maybe with plug-ins development.

    Some ideas:

    to extend functions of code editor with find/replace, reformat, code folding... with one click to extend functions of file browser with find/replace for files and folders and content (with regex), zip compression, full properties on files and folders (size, last edited data, if file is editable or not, so I'd like to block some files or folder by editing them, ... ) to extend functions to link Pythonista to any computer for comfortable development of Pythonista/Python scripts using big pc keyboard (my iphone is little and to use WebIDE) we need a wifi shared, not always available, but maybe with bluetooth could be possible using only pure python libraries or scripts, to extend a possible free remote connection service/interface if you want to make calculations that require not-pure python libraries not present in Pythonista (scipy, pandas, etc..) and with a full and complete integration with the app environment (example: my script, to run, needs some scipy functions, ok, I write it in Pythonista and I execute the entire script with Pythonista interpreter, and only the code that requires scipy is executed by the server with full working input-output capabilities), to extend internal site-packages folder in order to be able to delete not used pure-python libraries, since we can reinstall them with pip (using StaSH for example).

    Thank you

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

  • @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!

  • As far as I know, apps can only load libraries that are a part of iOS or that came with the app. This is based on the code signature, and not on the framework location. (For example, you can copy one of Pythonista's internal frameworks and load the copy without any issues using ctypes.) It's not possible to load frameworks that were signed for a different app. (For example you cannot copy a Pythonista framework to Editorial, even though both apps are from the same developer.) Frameworks that you compiled yourself using Xcode cannot be loaded either, even if you sign them with a development certificate. (The exception to that is @omz himself when using a dev build on Pythonista, because that is also signed with the dev cert. I remember there was a conversation about that on Twitter a while back, where omz could load a dev-cert-signed framework, but others couldn't.)

  • 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 :)

  • Thank you! Yes it does work!
    On the 7 Plus I'm able to access all 4 cameras this way. This is what I get and it works perfect:

    "<AVCaptureFigVideoDevice: 0x12db72c40 [Back Camera][com.apple.avfoundation.avcapturedevice.built-in_video:0]>",
    "<AVCaptureFigVideoDevice: 0x12dbeb240 [Front Camera][com.apple.avfoundation.avcapturedevice.built-in_video:1]>",
    "<AVCaptureFigVideoDevice: 0x12dbe1b20 [Back Telephoto Camera][com.apple.avfoundation.avcapturedevice.built-in_video:2]>",
    "<AVCaptureFigVideoDevice: 0x12dbe6bf0 [Back iSight Duo Camera][com.apple.avfoundation.avcapturedevice.built-in_video:3]>"

  • https://github.com/jsbain/objc_hacks with a "c" on the objc

  • @cvp , thanks for replying. I also had a wick go with launcher. Also no luck. It's ok. Not a big deal. Just a nice to have 🙄😬

  • @lukaskollmer I would be very surprised if this API isn't shut down for third-party apps in one of the next iOS updates. While it is a private API, and you wouldn't get through app review calling it directly, there are obviously lots of ways you could get around those checks...

  • Thanks, i didn't think about ui. The @ProfSpaceCadet example was goot but was a bit overkill for now.Currently I am experimenting with the ui method. :-)

  • objc_util should usually be smart enough to figure this out automatically. If you attempt to call _doSomethingWithParam_, it will first try to translate that to :doSomethingWithParameter:, but if that method doesn't exist (which is very likely), it'll try all permutations of underscores and colons for replacing the underscores in the method name, and it should eventually arrive at _doSomethingWithParameter: (in this case, there are only 4 possible permutations).

    There could theoretically be cases where both _doSomethingWithParameter and :doSomethingWithParameter: are valid methods (unlikely, but possible) – in those cases, you could construct an ObjCInstanceMethod manually like this: ObjCInstanceMethod(some_obj, '_doSomethingWithParameter:'). This would also be slightly faster because there's no guessing involved to figure out the correct selector.

    Long story short, calling _addActionWithTitle_image_style_handler_ should "just work".

  • That's weird. I wrote and tested the script on my iPad. Did you run the exact script in the linked post? Should be the second script that doesn't crash.

    Here is the code, if you don't care to guess.


    # coding: utf-8 from objc_util import * import ctypes import ui SUIViewController = ObjCClass('SUIViewController') UIAlertController = ObjCClass('UIAlertController') UIAlertAction = ObjCClass('UIAlertAction') def ok_pressed(sender): print 'OK pressed', ObjCInstance(sender), dir(ObjCInstance(sender)) alert = UIAlertController.alertControllerWithTitle_message_preferredStyle_(ns('My Alert'), ns('My Message'), 0) alert_action_block = ObjCBlock(ok_pressed, None, [c_void_p]) default_action = UIAlertAction.actionWithTitle_style_handler_(ns('OK'), 0, alert_action_block) alert.addAction_(default_action) ##rvc.presentModalViewController_animated_(alert, True) ## Stop Crashes retain_global(alert_action_block) def button_tapped(sender): super_view = sender.superview super_view_pntr = ObjCInstance(super_view) vc = SUIViewController.viewControllerForView_(super_view_pntr) vc.presentModalViewController_animated_(alert, True) view = ui.View(frame=(0,0,500,500)) view.name = 'Demo' view.background_color = 'white' button = ui.Button(title='Tap me!') button.center = (view.width * 0.5, view.height * 0.5) button.flex = 'LRTB' button.action = button_tapped view.add_subview(button) view.present('sheet')
  • Jon - thanks, you set me on the right track -- the app I want to paste into (MarginNote) accepts rich text only if it's formatted as an Apple Web Archive type. Here's how I ultimately got it to work for Python 2.7, thanks to this guide on coercing HTML into an archive type:

    from objc_util import * import os import base64 theDefinition = '<html><head></head><body>''<font size="5">' + '<b>Hello</b> <i>world!2</i>' + '</font></body></html>' theData = base64.encodestring(theDefinition) theData = str(theData) theArchive = """<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>WebMainResource</key> <dict> <key>WebResourceData</key> <data> """ + theData + """ </data> <key>WebResourceFrameName</key> <string></string> <key>WebResourceMIMEType</key> <string>text/html</string> <key>WebResourceTextEncodingName</key> <string>UTF-8</string> <key>WebResourceURL</key> <string>about:blank</string> </dict> </dict> </plist>""" thePasteBoard = ObjCClass('UIPasteboard') thePasteBoard = thePasteBoard.generalPasteboard() theType = "Apple Web Archive pasteboard type" thePasteBoard.setValue_forPasteboardType_(theArchive,theType)
  • I have updated the GitHub repo to represent the current work. I have more or less temporariely resolved the issue by calling reload(GLKit.view) in main.py how ever this is really only a temporary fix. I will look into some of the methods that omz uses to retain the globals/delegate methods.

  • if you change the retainme line so that it is stored in a built in package, it will ensure it does not get gc'd when rerunning. As is, when you click play again, it results in a crash, because the objc object still exists, but the callback doesn't.

    ui._retain_me = tabBar_didSelectItem_
Internal error.

Oops! Looks like something went wrong!