Thank you for a fast reply.
I investigated the web based route and found out that it's impossible to use with my current infrastructure because of the SSL certificates on a localhost.
As I understand, the only option left is to use the StoreKit API.
In theory, is it possible to use the StoreKit API from Python with the help of PyObjc (pyobjc-framework-StoreKit)?
Thank you,
Alex.
Post
Replies
Boosts
Views
Activity
Thank you, Matt. After reading your answer, I got a new idea. What if, I write a program in objective-c using the StoreKit API, for example I will define functions like get_products, request_payment, etc using the StoreKit API. Then, I will compile it and write a wrapper around it using Python's built-in ctypes module, and call it when necessary, for example after user presses "Buy button" or something like this. If I'm not wrong, it may be easier to use this method in order to add in-app purchases, rather than using pyobjc. What do you think?
evernote_appleid.txt
upnote.txt
nimbus.txt
Hello.
Sadly, I still didn't resolve my issue. I continued my investigation, and found very interesting detail:
I tried to buy some IAP in Evernote (built with Electron) and I couldn't do it.
I opened Evernote and recorded the log in Console app, and we saw the following message in the log:
default 19:09:24.479326 +0200 storeuid Error checking server purchase queue: Error Domain=com.apple.commerce.server Code=1001 "MZFinance.NoAccount_message" UserInfo={NSLocalizedDescription=MZFinance.NoAccount_message}
It's MZFinance.NoAccount_message again, exactly the same error as I have!
We opened UpNote (built with Electron) and the same error occurred.
We also did the same thing with "Nimbus Note" (also built with Electron), and got the same error.
This is very strange, but as you can see, my program's code is not the issue here.
I attach 3 logs recorded with Console app, each log made while opening Evernote, UpNote, and Nimbus app.
I doubt that such popular and big app as Evernote has problems with IAP, probably it's related to the environment.
Please let me know your thoughts about these strange errors :)
Thank you for your reply and suggestions.
As you recommended, I replaced the Electron with another Python app, and successfully reproduced the error!
So the problem is not with the Electron but maybe related to the security.inherit.
So, what I did:
Created two python programs "main" and "child", and packaged them with py2app.
The child app is located like this:
-- Main App.app/Contents/MacOS/Child connection test.app
"Main" just starts the "child" using the "open" command, then the "child" requests some website (in my case "worldtimeapi.org").
I signed these two programs and embedded the provisioning profile.
Result: The "main" successfully launched the "child", but the "child" crashed due to a network error.
Here is the child's terminal output:
File "urllib3/connection.pyc", line 174, in _new_conn
File "urllib3/util/connection.pyc", line 72, in create_connection
File "socket.pyc", line 954, in getaddrinfo
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "urllib3/connectionpool.pyc", line 703, in urlopen
File "urllib3/connectionpool.pyc", line 398, in _make_request
File "urllib3/connection.pyc", line 239, in request
File "http/client.pyc", line 1285, in request
File "http/client.pyc", line 1331, in _send_request
File "http/client.pyc", line 1280, in endheaders
File "http/client.pyc", line 1040, in _send_output
File "http/client.pyc", line 980, in send
File "urllib3/connection.pyc", line 205, in connect
File "urllib3/connection.pyc", line 186, in _new_conn
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x105927700>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "requests/adapters.pyc", line 440, in send
File "urllib3/connectionpool.pyc", line 785, in urlopen
File "urllib3/util/retry.pyc", line 592, in increment
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='worldtimeapi.org', port=80): Max retries exceeded with url: /api/timezone/Europe/London (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x105927700>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/root1/fourorganizer/MyQuickMac/bin/net_test/dist/Main test.app/Contents/MacOS/Connection test.app/Contents/Resources/__boot__.py", line 130, in <module>
_run()
File "/Users/root1/fourorganizer/MyQuickMac/bin/net_test/dist/Main test.app/Contents/MacOS/Connection test.app/Contents/Resources/__boot__.py", line 84, in _run
exec(compile(source, path, "exec"), globals(), globals())
File "/Users/root1/fourorganizer/MyQuickMac/bin/net_test/dist/Main test.app/Contents/MacOS/Connection test.app/Contents/Resources/connection_test.py", line 3, in <module>
r = requests.get('http://worldtimeapi.org/api/timezone/Europe/London')
File "requests/api.pyc", line 75, in get
File "requests/api.pyc", line 61, in request
File "requests/sessions.pyc", line 529, in request
File "requests/sessions.pyc", line 645, in send
File "requests/adapters.pyc", line 519, in send
requests.exceptions.ConnectionError: HTTPConnectionPool(host='worldtimeapi.org', port=80): Max retries exceeded with url: /api/timezone/Europe/London (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x105927700>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
Part 2, it didn't fit into one message.
In the Console, I see this:
default 12:58:50.396796 +0200 systemsoundserverd 202: AudioFileReadPackets:result 0
default 12:58:50.450804 +0200 opendirectoryd AuthenticationAllowed: Evaluation result for record "root1", record type "users": Success
default 12:58:50.569033 +0200 trustd cert[2]: AnchorTrusted =(leaf)[force]> 0
default 12:58:50.576198 +0200 secinitd MacOS error: -67050
default 12:58:51.027905 +0200 trustd cert[2]: AnchorTrusted =(leaf)[force]> 0
default 12:58:51.037686 +0200 secinitd MacOS error: -67050
error 12:58:51.131837 +0200 WindowServer [ERROR] - Unknown CGXDisplayDevice: 0x41dc9d00
error 12:58:51.133565 +0200 WindowServer [ERROR] - Unknown CGXDisplayDevice: 0x41dc9d00
default 12:58:51.656016 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 1
default 12:58:52.632375 +0200 symptomsd rssi (-74) or transmitRate (78.000000) changed on interface en1 for BSSID:98:da:c4:29:43:03
default 12:58:52.656344 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 2
default 12:58:53.657230 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 3
default 12:58:54.658477 +0200 Connection test dnssd_clientstub ConnectToServer: connect() failed path:/var/run/mDNSResponder Socket:5 Err:-1 Errno:1 Operation not permitted
default 12:58:54.661882 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 1
default 12:58:55.663223 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 2
default 12:58:56.664690 +0200 Connection test dnssd_clientstub ConnectToServer: connect()-> No of tries: 3
default 12:58:57.640320 +0200 symptomsd rssi (-76) or transmitRate (78.000000) changed on interface en1 for BSSID:98:da:c4:29:43:03
default 12:58:57.665647 +0200 Connection test dnssd_clientstub ConnectToServer: connect() failed path:/var/run/mDNSResponder Socket:5 Err:-1 Errno:1 Operation not permitted
I googled this "Err:-1 Errno:1 Operation not permitted" error" and found out that it happens when the .app doesn't have proper entitlement for outgoing connections.
So, the child doesn't inherit the entitlements from the "main".
You said that "open" is not a proper way to launch the child app, so which method should I use to start it properly?
So, how should I properly launch the child so it inherits the main app's entitlements?
A bit about the entitlements:
codesign -dv --entitlements - "dist/Main test.app"
<?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>com.apple.application-identifier</key>
<string>MY_TEAM_ID.com.abtco.myquickmaclite</string>
<key>com.apple.developer.team-identifier</key>
<string>MY_TEAM_ID</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>MY_TEAM_ID.com.abtco.myquickmaclite</string>
</array>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
codesign -dv --entitlements - "dist/Main test.app/Contents/MacOS/Connection test.app"
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
<key>com.apple.application-identifier</key>
<string>MY_TEAM_ID.com.abtco.myquickmaclite</string>
<key>com.apple.developer.team-identifier</key>
<string>MY_TEAM_ID</string>
<key>com.apple.security.application-groups</key>
<array>
<string>MY_TEAM_ID.com.abtco.myquickmaclite</string>
</array>
</dict>
</plist>
If I remove these "team-identifier" or "application groups" entitlements, it doesn't start.
If you need any other information (maybe info.plist, or something else), please let me know, and I will send it to you ASAP.
Thank you for your time and response.
Ok. As I understand, you recommend me to configure Electron's sandbox independently. So, I will need to remove the security.inherit and it will work? If I do it, can Electron stay in the MacOS directory? Do I need to move it to other directory like Frameworks or somewhere else? I will try it and update. Thank you.
So, I tried resigning Electron app as the main app and embedding it into the Python app.
The result stays the same: it doesn't load the server's webpage and it can't make any network requests.
I still launch it with the "open" command (I still don't have any alternatives).
But right now, it has its own entitlements required to send network requests, why doesn't it work?
Any ideas on how this can be resolved?
Here's the Console log:
log.txt