Pythonista-Issues
Pythonista-Issues copied to clipboard
Multipeer Connectivity example not working in 3.4
The example (mentioned in closed issue support #501)
System Information
- Pythonista N/A (N/A), Default interpreter 3.10.4
- iOS 16.5, model iPad7,5, resolution (portrait) 1536.0 x 2048.0 @ 2.0
When run multipeer.py and enter name get Message: MultipeerConnectivity framework error
The actual error message is:
The operation couldn’t be completed. (NSNetServicesErrorDomain error -72008.)
It looks like since iOS 14 there has been a new security requirement where multipeer (Bonjour) network usage must be declared in plist as follows:
<key>NSBonjourServices</key>
--
<array>
<string>_multipeertest._tcp</string>
</array>
… where multipeertest
should match the service key provided to the multipeer framework.
This is a problem for Pythonista, since it is only one app from Apple’s point of view, with a singular plist.
In theory, there could be a known value set in plist, which would then be used for all multipeer Pythonista scripts. To ensure that you only connect peers expected by your script, you would need to add some additional validation to filter peers by initial data.
Thanks for the info. With the 'help' of Chat GTP-3 I got understanding about what is required. Is the service key, that same as the server_type string in your MultipeerConnectivity class? (If so should the same restrictions eg 1-15 chars.. apply). Should a request for adding the key to the plist be made? Chat GTP-3 (with quite a bit of prompting) suggested code below to modify the plist but for me to discover that overwriting it is not permitted. Cheers, Bill
import objc_util
from plistlib import dumps, loads
bundle_id = objc_util.ObjCClass('NSBundle').mainBundle().bundleIdentifier()
main_bundle = objc_util.ObjCClass('NSBundle').bundleWithIdentifier_(bundle_id)
info_plist_path = str(main_bundle.pathForResource_ofType_('Info', 'plist'))
with open(info_plist_path, 'rb') as f:
info_plist_data = f.read()
info_plist = loads(info_plist_data)
info_plist['NSBonjourServices'] = 'mptest-tcp'
modified_info_plist_data = dumps(info_plist)
with open(info_plist_path, 'wb') as f:
f.write(modified_info_plist_data) ## fails
Yes. Apple's iOS security will not allow the modification of any application's permissions except when digitally signed by the application's original author prior to Apple's review for submission into the App Store.
import objc_util
from plistlib import dumps, loads
bundle_id = objc_util.ObjCClass('NSBundle').mainBundle().bundleIdentifier()
main_bundle = objc_util.ObjCClass('NSBundle').bundleWithIdentifier_(bundle_id)
info_plist_path = str(main_bundle.pathForResource_ofType_('Info', 'plist'))
with open(info_plist_path, 'rb') as f:
info_plist_data = f.read()
info_plist = loads(info_plist_data)
-->
import plistlib
import sys
from pathlib import Path
info_plist = plistlib.loads((Path(sys.executable).parent / "Info.plist").read_bytes())