Godot version:
3.2 Alpha, 3.2 Beta1, 3.2 Beta2
OS/device including version:
Tested on iOS 12/13
Issue description:
Godot automatically asks for camera access at startup wich causes the app to crash on certain devices and leads to the app rejection when you try to publish it.
I could reproduce the issue on an iPhone 5S using iOS12 (works fine on iPhone X and iPad Pro and iOS13). The App does not crash when you delete the "Privacy - Camera Usage Description" but Godot still tries to get permission and the App can not be uploaded to the App store.
I am trying to release a game for children and, apart from being unable to publish it, Godot asking for Camera access on startup is quite problematic.
My code does not contain any references to the camera, microphone or arkit. Everything is deselected and I have tried to exclude them using the entitlement description.
I have tried Godot 3.1, Godot 3.2 Alpha and both Betas. I have also tried to revert to 3.1.2RC1 but it does not recognize the .tscn files after they have been opened in 3.2
At the moment it is not possible for me to release the app due to this issue.
Steps to reproduce:
Upload any project to iOS App store
Minimal reproduction project:
Yes, this is really problematic, confirmed. A similar issue has been raised pre-beta2 related to the packaging of ArKit and has been addressed by @bruvzg and @BastiaanOlij in [this PR] (https://github.com/godotengine/godot/pull/33759) but more needs to be done to resolve this properly and unfortunately I am not very up to speed with iOS and the build chain. I can help with testing though.
Also happening here on 3.2 beta 2.
Godot should not request camera access when "Camera usage description" is empty or missing: https://github.com/godotengine/godot/blob/master/platform/iphone/camera_ios.mm#L401-L410 (added in #30374), so it must be requested by some other code.
If the "Camera Privacy" entry is not set (delete the key or leave the "value" field empty) the Xcode Debugger output reads: "No NSCameraUsageDescription key in pList, no access to cameras." Apple will not to accept the build and send an email with the following statement:
"ITMS-90683: Missing Purpose String in Info.plist - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSCameraUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs."
No NSCameraUsageDescription key in pList, no access to cameras
Yep, this is message from the Godot itself indicating camera init is skipped.
ITMS-90683: Missing Purpose String in Info.plist
Well, looks like just having camera code is enough to trigger this.
If this is the case we'll probably need to ship multiple versions of the export templates compiled with and without camera (and most likely microphone) support.
Or somehow split all sensitive the code into multiple static libs and load it dynamically.
Or somehow split all sensitive the code into multiple static libs and load it dynamically.
Here's basic mock-up:
AFAIK iOS dlsym doesn't work on RTLD_SELF and apps with .dylibs are not accepted to the App Store, so loading camera server code at the runtime is not an option.
1. Compile camera server code to the separate static lib (additionally make empty/stub lib version).
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 85ba56165b..0c492f4553 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -14,12 +14,25 @@ iphone_lib = [
'in_app_store.mm',
'icloud.mm',
'ios.mm',
+]
+
+iphone_camera_lib_real = [
'camera_ios.mm',
]
+iphone_camera_lib_stub = [
+ 'camera_ios_stub.mm',
+]
+
env_ios = env.Clone()
ios_lib = env_ios.add_library('iphone', iphone_lib)
+env_ios_camera_real = env.Clone()
+ios_lib_camera_real = env_ios_camera_real.add_library('iphone_camera_real', iphone_camera_lib_real)
+
+env_ios_camera_stub = env.Clone()
+ios_lib_camera_stub = env_ios_camera_stub.add_library('iphone_camera_stub', iphone_camera_lib_stub)
+
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
if "osxcross" in env:
diff --git a/platform/iphone/camera_ios_stub.mm b/platform/iphone/camera_ios_stub.mm
new file mode 100644
index 0000000000..f724171df3
--- /dev/null
+++ b/platform/iphone/camera_ios_stub.mm
@@ -0,0 +1,12 @@
+/*************************************************************************/
+/* camera_ios_stub.mm */
+/*************************************************************************/
+
+#include "camera_ios.h"
+#include "servers/camera/camera_feed.h"
+
+void CameraIOS::update_feeds() { /*NOP*/ }
+
+CameraIOS::CameraIOS() { /*NOP*/ }
+
+CameraIOS::~CameraIOS() { /*NOP*/ }
Been a bit preoccupied lately, sorry for jumping in late.
This is pretty horrible from Apple, it really makes it hard for generic
engines to operate. There are other features that fall under this type of
protection, having separate builds for each possible combination sounds
whack.
Seeing we do the final compile in xcode, would there be a way to
restructure this so we isolate the bits of logic in modules but instead of
compiling in the modules we add them as separate lib files? So we have a
dummy version and implemented version compiled and deployed in the template.
Then on export we decide which libraries to link in?
On Thu, 28 Nov 2019 at 11:51 pm, bruvzg notifications@github.com wrote:
Or somehow split all sensitive the code into multiple static libs and load
it dynamically.Here's basic mock-up:
AFAIK iOS dlsym doesn't work on RTLD_SELF and apps with .dylibs are not
accepted to the App Store, so loading camera server code at the runtime is
not an option.
- Compile camera server code to the separate static lib (additionally
make empty/stub lib version).diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 85ba56165b..0c492f4553 100644--- a/platform/iphone/SCsub+++ b/platform/iphone/SCsub@@ -14,12 +14,25 @@ iphone_lib = [
'in_app_store.mm',
'icloud.mm',
'ios.mm',+]++iphone_camera_lib_real = [
'camera_ios.mm',
]
+iphone_camera_lib_stub = [+ 'camera_ios_stub.mm',+]+
env_ios = env.Clone()
ios_lib = env_ios.add_library('iphone', iphone_lib)
+env_ios_camera_real = env.Clone()+ios_lib_camera_real = env_ios_camera_real.add_library('iphone_camera_real', iphone_camera_lib_real)++env_ios_camera_stub = env.Clone()+ios_lib_camera_stub = env_ios_camera_stub.add_library('iphone_camera_stub', iphone_camera_lib_stub)+
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
if "osxcross" in env:diff --git a/platform/iphone/camera_ios_stub.mm b/platform/iphone/camera_ios_stub.mm
new file mode 100644
index 0000000000..f724171df3--- /dev/null+++ b/platform/iphone/camera_ios_stub.mm@@ -0,0 +1,12 @@+/***********************/+/* camera_ios_stub.mm /+/***********************/++#include "camera_ios.h"+#include "servers/camera/camera_feed.h"++void CameraIOS::update_feeds() { /NOP/ }++CameraIOS::CameraIOS() { /NOP/ }++CameraIOS::~CameraIOS() { /NOP*/ }
- On export include either real camera lib or stub (or generate stub code
in place) to the Xcode project.—
You are receiving this because you were assigned.Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/33918?email_source=notifications&email_token=AAO262LSEZ4MJOGY7ZFND3TQV65FXA5CNFSM4JR2QPW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFMQSBI#issuecomment-559483141,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAO262M4TX7EIFFVV6ALBR3QV65FXANCNFSM4JR2QPWQ
.>
Kindest regards,
Bastiaan Olij
https://www.facebook.com/bastiaan.olij
https://twitter.com/mux213
https://www.youtube.com/BastiaanOlij
https://www.youtube.com/channel/UCrbLJYzJjDf2p-vJC011lYw
https://github.com/BastiaanOlij
A bit more advanced mock-up - https://github.com/bruvzg/godot/tree/ios_modular_build:
camera module.libgodot_{module_name}_module.iphone.{release/debug}.{arch}.a static libs.register_module_types.gen.cpp for selected modules on demand. @bruvzg you're a god dude :) I have to find time to play around with this.
@bruvzg Looks good and a sensible thing to do. Go for it.
Most helpful comment
A bit more advanced mock-up - https://github.com/bruvzg/godot/tree/ios_modular_build:
cameramodule.libgodot_{module_name}_module.iphone.{release/debug}.{arch}.astatic libs.register_module_types.gen.cppfor selected modules on demand.