google-ar / arcore-ios-sdk

ARCore SDK for iOS
https://developers.google.com/ar/
Apache License 2.0
283 stars 84 forks source link

Arcore depends on Firebase, then duplicate symbols in iOS app that use Firebase too #95

Open lucarocchi opened 10 months ago

lucarocchi commented 10 months ago

To me, the fact that Arcore is an umbrella framework to Firebase makes it unusable by iOS app that also uses Firebase , because of duplicate symbols . Does anyone knows an effective solution for that ?

15kingben commented 10 months ago

Are you building with Cocoapods or Swift Package Manager?

lucarocchi commented 10 months ago

I have tried many .. I mean only SPM , only pod , mixed and many combination ... at first the problem comes at compile time,but I was able to solve , but then crash appears at runtime ... if I remove Firebase from my app everything works

if Firebase is used on my app Xcode console show errors like this....

objc[8956]: Class FIRInstallationsErrorUtil is implemented in both /private/var/containers/Bundle/Application/EE0FB4F1-DFB7-4A15-8781-DE1336275BEA/Loquis.app/Frameworks/UnityFramework.framework/UnityFramework (0x10bcbd960) and /private/var/containers/Bundle/Application/EE0FB4F1-DFB7-4A15-8781-DE1336275BEA/Loquis.app/Loquis (0x101cd0c38). One of the two will be used. Which one is undefined. objc[8956]: Class FIRInstallationsHTTPError is implemented in both /private/var/containers/Bundle/Application/EE0FB4F1-DFB7-4A15-8781-DE1336275BEA/Loquis.app/Frameworks/UnityFramework.framework/UnityFramework (0x10bcbd988) and /private/var/containers/Bundle/Application/EE0FB4F1-DFB7-4A15-8781-DE1336275BEA/Loquis.app/Loquis (0x101cd0c60). One of the two will be used. Which one is undefined.

then

10.19.1 - [FirebaseCore][I-COR000003] The default Firebase app has not yet been configured. AddFirebaseApp.configure()to your application initialization. This can be done in in the App Delegate's application(_:didFinishLaunchingWithOptions:) (or the @main struct's initializer in SwiftUI).`

finally it crash

** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FBLPromise HTTPBody]: unrecognized selector sent to instance 0x282f7ed30'
*** First throw call stack:
(0x198194870 0x1904b3c00 0x19822519c 0x1980d9ff8 0x19821ab10 0x1096bc7ec 0x1096bbf8c 0x1096596b4 0x1038e4f50 0x1038e6b34 0x1038eeba4 0x1038ef728 0x1038fc5f8 0x1038fbc2c 0x201b05964 0x201b05a04)
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FBLPromise HTTPBody]: unrecognized selector sent to instance 0x282f7ed30'
*** First throw call stack:
(0x198194870 0x1904b3c00 0x19822519c 0x1980d9ff8 0x19821ab10 0x1096bc7ec 0x1096bbf8c 0x1096596b4 0x1038e4f50 0x1038e6b34 0x1038eeba4 0x1038ef728 0x1038fc5f8 0x1038fbc2c 0x201b05964 0x201b05a04)
[0x125f6c800] Created session
[0x0] Releasing session
[0x125f6c800] Releasing session
Uncaught exception: NSInvalidArgumentException: -[FBLPromise HTTPBody]: unrecognized selector sent to instance 0x282f7ed30
(
    0   CoreFoundation                      0x000000019819487c B37A1273-B0C2-312E-9E0B-7143FB645C69 + 968828
    1   libobjc.A.dylib                     0x00000001904b3c00 objc_exception_throw + 60
    2   CoreFoundation                      0x000000019822519c B37A1273-B0C2-312E-9E0B-7143FB645C69 + 1560988
    3   CoreFoundation                      0x00000001980d9ff8 B37A1273-B0C2-312E-9E0B-7143FB645C69 + 204792
    4   CoreFoundation                      0x000000019821ab10 _CF_forwarding_prep_0 + 96
    5   UnityFramework                      0x00000001096bc7ec -[GDTCCTUploadOperation updateNextUploadTimeWithResponse:forTarget:] + 52
    6   UnityFramework                      0x00000001096bbf8c __54-[GDTCCTUploadOperation uploadBatch:toTarget:storage:]_block_invoke + 56
    7   UnityFramework                      0x00000001096596b4 __56-[FBLPromise chainOnQueue:chainedFulfill:chainedReject:]_block_invoke.18 + 52
    8   libdispatch.dylib                   0x00000001038e4f50 _dispatch_call_block_and_release + 32
    9   libdispatch.dylib                   0x00000001038e6b34 _dispatch_client_callout + 20
    10  libdispatch.dylib                   0x00000001038eeba4 _dispatch_lane_serial_drain + 1368
    11  libdispatch.dylib                   0x00000001038ef728 _dispatch_lane_invoke + 408
    12  libdispatch.dylib                   0x00000001038fc5f8 _dispatch_root_queue_drain_deferred_wlh + 328
    13  libdispatch.dylib                   0x00000001038fbc2c _dispatch_workloop_worker_thread + 444
    14  libsystem_pthread.dylib             0x0000000201b05964 _pthread_wqthread + 288
    15  libsystem_pthread.dylib             0x0000000201b05a04 start_wqthread + 8
)
libc++abi: terminating due to uncaught exception of type NSException

objc[8956]: Class _TtGCs18_DictionaryStorageSSGV20FirebaseCoreInternal13WeakContainerCS0_16HeartbeatStorage__$ is implemented in both ?? (0x13b525b28) and /usr/lib/swift/libswiftCore.dylib (0x1e91273a0). One of the two will be used. Which one is undefined.

I have to add that in the log above you see UnityFramework that in turn link Arcore ... but this is not the point ... I have tried also to use Arcore by itself in my app , removing UnityFramework , but duplicated symbols or "class implemented in both module" remain the same

15kingben commented 10 months ago

When building on iOS with Unity, Cocoapods is the only supported build system. ARCore has a dependency on Firebase, so if using another Firebase target, it will need to be correctly included in the Podfile, otherwise duplicate symbols will occur. Other methods of bundling won't work.

What errors do you get when including the Firebase target via the Podfile?

lucarocchi commented 10 months ago

thank you for suggestion , I think I have already tried but I will retry to be sure and to report result... so , as you know , when you get the iOS export from Unity+ ARCore it setup the podfile as follow:


source 'https://cdn.cocoapods.org/'
platform :ios, '12.0'
target 'UnityFramework' do
  pod 'ARCore/GARSession', '~> 1.40.0'
  pod 'ARCore/Geospatial', '~> 1.40.0'
end
target 'Unity-iPhone' do
end
use_frameworks! :linkage => :static

1 )  I will build Unity export as it is 
2)  I will include "Unity as library" in my workspace (I have done that before with another "Unity without Arcore" successfully) 
3) Makes sure my app is using pod Firebase , not SPM 

4) Build and cross fingers

Does that are the steps you suggest to follow ?
15kingben commented 10 months ago

Yes, so in the generated podfile you would need to add you something like pod 'Firebase/Database', '~> 8.0' for whichever target you are using, and then run pod install. The version selected might be important for compatibility with the ARCore dependency. There is also an option to disable automatic podfile generation in "iOS Resolver Setttings" in Unity.

I'm not familiar with "Unity as library", but it may be worth trying without that feature as well.

lucarocchi commented 10 months ago

It's not possibile to add MyApp target in the unity generated pod . "Unity as library" is the term they use at Unity, see https://docs.unity3d.com/Manual/UnityasaLibrary-iOS.html So for example you have your Xcode workspace with MyApp project and target ,with its own podfile and firebase stuff. Then you have to import the Unity generated projects under the same workspace with its own podfile that have dependency on Arcore and in turn on Firebase the Unity projects when built with its podfile too, produces a UnityFramework that depends on Arcore -> Firebase So when that Unityframework is added as dependency to main app duplicated issues happens... at least that is my understanding

I suppose that Arcore primary goal is not to be used in a Unity module that have to integrate within another iOS app , but that was working until you do not use Arcore on Unity side,and now seems to be broken That is the scenario I'm looking for a solution...

By the way , I'm evaluating to move to iOS native Arcore integration as for GeoSpatial example , but that would be the last option , only if not other solution available

15kingben commented 10 months ago

If I understand these docs correctly, I can see why this might result in duplicate symbols. Although you run pod install on the generated project, it seems like the binary from that project is just directly copied over, meaning it would not be managed by Cocoapods in the host project, resulting in duplicate symbols. I suppose you could try to add the other Firebase target in the generated Unity project and remove it from the host app, but that may not even work. In this case using the native API's might be easier.