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.
Pythonista xCode template adventure
-
Hi Pythonistaers!
I have a problem with a discrepancy between the xCode template and Pythonista 1.6 betaversions of an app, resulting in different code paths depending on if it's run from within the Pythonista app or it's own app /in an xCode simulator. (xCode simulator and self-contained app have the same results. Pythonista scripts don’t, but they behave as expected.)
the specific piece of code where the divergence takes place is in the try-except fork below. Pythonista-launched app succeeds the try clause. xCode/self-contained-app fails and excepts.
Based on the piece of code where this divergence happens, and error logs, I believe this has to do with the way location services work.ourActualLocation = [] print "..." location.start_updates() print "...." thisLoc = location.get_location() print thisLoc print "....." try: #works w/pythonista launched app thisLon = thisLoc["longitude"] thisLat = thisLoc["latitude"] except: #excepts with simulator and app bundle print "gps module offline...using napa coordinates fallback..." thisLon = -125.3353 thisLat = 39.3101 print "......" ourActualLocation = [thisLat,thisLon] print "......." location.stop_updates() #addressStart = #[39.2960,-125.2830] addressEnd = [39.3101,-125.3353]#getCoor
Here is part of an error log:
Oct 29 21:26:24 syht8387235u locationd[3928]: ERROR: com.mycompany.PythonistaFiveStars is depending on legacy on-demand authorization, which is not supported for new apps Oct 29 21:26:54 --- last message repeated 1 time --- Oct 29 21:26:54 syht8387235u assertiond[3929]: assertion failed: 15B42 13B134: assertiond + 13207 [F9316174-60A2-3CA9-A8AD-49680DCA196D]: 0x1 Oct 29 21:27:26 syht8387235u assertiond[3929]: assertion failed: 15B42 13B134: assertiond + 13207 [F9316174-60A2-3CA9-A8AD-49680DCA196D]: 0x1 Oct 29 21:27:52 --- last message repeated 7 times --- Oct 29 21:27:52 syht8387235u PythonistaFiveStars[3976]: -canOpenURL: failed for URL: "launch://" - error: "This app is not allowed to query for scheme launch" Oct 29 21:30:58 syht8387235u routined[3913]: CoreLocation: Error occurred while trying to retrieve motion state update: CMErrorDomain Code:104
Also, another error: The template/app bundle can’t load piano sounds included in the sound module.[SOLVED - see below]Error Log:
2015-10-30 02:16:00.923 PythonistaFiveStars[2373:100188] OAL Error: -[OALSimpleAudio internalPreloadEffect:reduceToMono:]: Could not load effect Piano_C.caf 2015-10-30 02:16:01.227 PythonistaFiveStars[2373:100188] OAL Error: -[OALSimpleAudio internalPreloadEffect:reduceToMono:]: Could not load effect Piano_3.caf Message from debugger: Terminated due to signal 15
So, in summary, the issues with the Template seem to be:
1.) location updates are different, something about "legacy" permissions?[SOLVED]
A: Create NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription
item in your info.plist, and choose the text description to show people in settings location pane.
surprisingly, correct me if I'm wrong, a dialogue only seems to pop up with NSLocationAlwaysUsageDescription2.) access to sounds in the sound module[SOLVED]
A: never mind - personal code bug.3.) While the script is running from within pythonista, it's able to remain in the background at least for a while. The self-contained app version does not stay open in the background AT ALL.[SOLVED]
A: change "application does not run in the background" to NO in plist file.4.) Out bound Webbrowser:// links to other apps don't seem to work.
I should probably include:
iPhone 6S plus / xCode-Beta.app v7.1 / iOS 9.1 / Pythonista 1.6 latest Beta (160035) / latest Pythonista template that I'm aware of.I'm going to use this thread as an ongoing exploration of issues with using the whole of the Pythonista development environment.
-
If you do not put in the try / except block, what exception type is thrown? (E.g.: NotImplemented, IOError, IndexError). I always worry when I see
except:
without one or more error types after it. It is too easy to swallow exceptions not related to what you are expecting.Does the XCode simulator usually support location calls in Swift or ObjC apps?
-
have you authorized your custom app for location services in the settings app? In pythonista yu usually get prompted, but i imagine xcode kight work differently?
-
re sounds, i believe you can use an absolute path.
os.path.join(os.path.split(os.__file__)[0],'../Media/Sounds/piano/G3.caf')
as least in the latest beta. older versions were arranged differently, but you should be able to start one or two folders up from the one containing os.file, the os.walk your way to fund the file you want. I think there was some code that did this a little while back posted on the forum.
-
by the by... do you control your own Info.plist in the xcode trmplate? seems like you would need to add permissions for location, and backgrounding there.
-
Thank you all for your replies! Unfortunately I'm a little stretched thin this weekend, so I might not be able to get to all of your responses thoroughly for a couple days.
So far, changing "Application does not run in the background" to NO in the plist file worked! (Double negative!?) Thanks!
@ccc : Will get back to you soon when I have a chance to play around with it.
@JonB : the only setting I could find for location services in the plist file was "Privacy - Location usage description" which I filled out. My app still doesn't show up in the Settings-Privacy->Location Services page on iOS. THEN, I created the field NSLocationWhenInUseUsageDescription and wrote something, and now my app DOES show up in the location services page of iOS settings. Will have to verify that location is working correctly as soon as I have a chance.
->the os.path.join trick seems to mostly work. I'm still getting :
PythonistaFiveStars[4174:1860369] OAL Error: +[OALTools urlForPath:]: Could not find full path of file Piano_A5.caf 2015-10-31 19:22:17.913 PythonistaFiveStars[4174:1860369] OAL Error: -[OALAudioFile initWithUrl:reduceToMono:]: Cannot open NULL file / url 2015-10-31 19:22:17.913 PythonistaFiveStars[4174:1860369] OAL Error: -[OALAudioFile bufferNamed:startFrame:numFrames:]: Attempted to read from closed file. Returning nil (url = (null)) 2015-10-31 19:22:17.914 PythonistaFiveStars[4174:1860369] OAL Error: -[OALSimpleAudio internalPreloadEffect:reduceToMono:]: Could not load effect Piano_A5.caf
and
PythonistaFiveStars[4174:1860369] OAL Error: +[OALTools urlForPath:]: Could not find full path of file Piano_B5.caf
and
PythonistaFiveStars[4174:1860369] OAL Error: -[OALSimpleAudio internalPreloadEffect:reduceToMono:]: Could not load effect Piano_B5.caf
even though I have these lines inserted in my main script:
os.path.join(os.path.split(os.__file__)[0],'../Media/Sounds/piano_C.caf') os.path.join(os.path.split(os.__file__)[0],'../Media/Sounds/piano_3.caf') os.path.join(os.path.split(os.__file__)[0],'../Media/Sounds/Piano_B5.caf') os.path.join(os.path.split(os.__file__)[0],'../Media/Sounds/Piano_A5.caf')
-
So location appears to be working. Thanks for your help, and I apologize for my incompetency!
@ccc You're absolutely right, I'm very irresponsible with my use of try except blocks. This time it turns out it was a plist setting that was stopping location from working, but I'll make an effort to get better at more granularly using exceptions in the future.
-
On the path, it is possible that the template has things in different spots from the current beta -- i think things were cleaned up and organized in the beta.
This thread
https://forum.omz-software.com/topic/1094/xcode-ui-file-loading-possible-bug-in-pythonista/16has a
find_bundled_files
script which you can use to look for caf files (set file_extension obviously). You may need to start from a path higher up. Once you find it, make note of the relative path relative to something like os.file or the path that scene returns. -
After much hair pulling and confusion on my part... turns out the Piano files referenced in the System log while building and running the app were not actual notes or files that I could seem to find (Piano_C.caf and Piano_3.caf), nor did I (mean to) reference them (on purpose). Turns out it was my code.
Nov 12 21:48:41 syht8387235u PythonistaFiveStars[987]: OAL Error: -[OALSimpleAudio internalPreloadEffect:reduceToMono:]: Could not load effect Piano_C.caf Nov 12 21:48:41 syht8387235u PythonistaFiveStars[987]: OAL Error: +[OALTools urlForPath:]: Could not find full path of file Piano_3.caf
My code:
if newSurgeLabel > 1.0: notes = 'C4','D4','E4','F4','G4','A5','B5' else: notes = 'C3'#, 'D3', 'B3'#, 'C3' for note in notes: sound.play_effect('Piano_' + note) time.sleep(.3)
in the else clause, for note in notes was reading 'C3' as a string rather than an array with a single item, since previously I had multiple items and I had commented them out. oops. Hence the Piano_C and Piano_3. So I changed:
notes = 'C3' ----changed to---> notes = [] notes.append('C3')
The lesson here is, when in doubt, it's probably my own code, not the most excellent Pythonista. Check back soon for the next exciting episode of "Tizzy mashes keys, hopes for best - season 1".
-
Hi everyone, just following up here.
webbrowser.open() doesn't appear to work as a standalone app through the Xcode template.
Previously I had mentioned that launching an outbound link to an app made my app freeze when used as a standalone app. I have a function tied to a button that would close the view and then open a link. I removed everything except an outbound link to http://www.apple.com, and still this doesn't work in the standalone version, just making the app freeze, and I don't see anything relevant in the system log output.
So, button tied to the following function:
def uberButtonPress(sender): webbrowser.open("http://www.apple.com") or def uberButtonPress(sender): webbrowser.open("launch://")
both versions of that function work properly when in pythonista itself, but not for the template.
Any ideas guys?
The only console output i could get from Xcode was this, but I don't think it's relevant. (I do use the speech module, so if anybody has any insight about these errors I'm very interested)
2015-11-17 11:41:22.103 PythonistaFiveStars[896:309538] |AXSpeechAssetDownloader|error| ASAssetQuery error fetching results (for com.apple.MobileAsset.MacinTalkVoiceAssets) Error Domain=ASError Code=21 "Unable to copy asset information" UserInfo={NSDescription=Unable to copy asset information} 2015-11-17 11:41:22.111 PythonistaFiveStars[896:309560] |AXSpeechAssetDownloader|error| ASAssetQuery error fetching results (for com.apple.MobileAsset.MacinTalkVoiceAssets) Error Domain=ASError Code=21 "Unable to copy asset information" UserInfo={NSDescription=Unable to copy asset information} 2015-11-17 11:41:22.111 PythonistaFiveStars[896:309560] Building MacinTalk voice for asset: (null)
Any ideas anyone about webbrowser.open() in the Xcode template?
-
I am concerned when you say you close the view, then open a webbrowser. Without a ui.delay, this can result in some race conditions that freeze the app. The timing in xcode is going to be a little different than in app, i think others have had similar issues.
Try: 1). launching webbrowser without ui, to see if webbrowser works at all.
2) if that works, trydef uberButtonPress(sender): def launchWebBrowser(): webbrowser.open('http://www.apple.com') ui.delay(launchWebBrowser, 1.0)
Does the webbrowser need to stay in app? if not, you could use safari-http:// to swicth to safari. Do you need the full webbrowser with addressbar,etc? mif not ui.WebView might work for you.
-
@JonB said:
safari-http://
Thanks for your reply, JonB. So, as you suggest, I removed everything from the function except the webbrowser.open() function, using both the safari-http:// and other app's url-schemes. None of them seem to work when running from an app built using the Pythonista template for xCode. Pressing the button associated with them doesn't make the app crash and close or anything like that, it simply makes the app's execution hang, freeze, and be unresponsive.
Once I figure out how to make webbrowser.open() work at all, I'll have to use ui.delay per your advice.
Is there anything else I can do to troubleshoot? It's my understanding that I can't simply use Objc_util because that's not integrated into the xCode template yet (please correct me if I'm wrong).
-
Have you created an app which does not us
ui
at all? i.e no button at all? -
also... i am pretty sure webview does work in the template. is there a reason you cannot use ui.WebView?
-
@JonB So I've experimented with this quite a bit and there are a couple things involved. (BTW i'm not actually trying to have a web view, but use the url schemes of other apps via these modules, but am using safari-http://www.apple.com for testing purposes.)
First off, for iOS 9 to be able to query url schemes you need to add an array into your plist called LSApplicationQueriesSchemes, filled with strings of all the app urls you want to use. for launch center pro, url "launch://", you use string "launch" in the plist array.
Turns out both ui.WebView and webbrowser.open() DO work in the template when tested on their own. In the context of my app, they have maybe a 5% success rate, the other 95% of the time the app freezes.
I have a main run loop that's constantly going, and making changes to labels etc if time passed since last change has been 1 second or more. So I guess the interrupt from using a button to launch a url is somehow interfering with this.
But again, the same exact files launched from within Pythonista, these buttons launching URLS work 100% of the time, where from an app using the Xcode template, almost none of the time.
ui.delay(webbrowser.open("safari-http://www.apple.com),1) results in the same freezing.
-
ui.delay takes a callable as the first argument. You provided a bool, after calling webbrowser.open! You will want to use a lambda or wrap in a def:
def launch(): webbrowser.open(url) ui.delay(launch,1.)
Is your main loop running as a thread? or just a main loop with sleeps?
I just read a little about LSApplicationQueriesSchemes... seems like this will kill the whole x-callback-url movement. if that was the problem here, it seems like it should just fail silently.
-
btw, use webbrowser.can_open to check if it is LSApplicationQueriesSchemes causing you problems.
-
sorry, one more question. if the problem is your main loop, you could kill your main loop's activity before launching the webbrowser; i.e check for a flag at the start if each loop, and make sure you delay long enough that the loop is done, or use a Semaphore, etc.