google-ar / arcore-ios-sdk

ARCore SDK for iOS

Home Page:https://developers.google.com/ar/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot properly include ARCore as a dependency to a custom Swift Framework

kkaun opened this issue · comments

commented

Our team is developing partner iOS Swift Framework (SDK) with some 3rd-party dependencies inside.

Framework itself has several 3rd-party dependencies all embedded with CocoaPods, and they're working like a charm either during compile time or while testing on device/simulator, while being embedded inside a simple test "partner" app. No general problems here.

But there is an issue with ARCore embedding via CocoaPods suite similar to #43 .

So we're currently stuck with using common workspace and 2 projects (test app and framework itself) within it, also with CocoaPods base structure on top workspace level:
Знімок екрана 2022-06-21 о 20 46 37
Знімок екрана 2022-06-21 о 21 49 49

The Podfile here currently looks like this, inspired by the structure mentioned here https://stackoverflow.com/a/42480097/6405022:

# platform :ios, '11.0'
workspace 'Untitled.xcworkspace'

abstract_target 'CommonPods' do
    # ... some other common 3rd-party dependencies here ...
    pod 'ARCore/AugmentedFaces', '~> 1.30.0'

    target 'TestApp' do
        project 'TestApp/TestApp.xcodeproj'
    end

    target 'Framework' do
        project 'Framework/Framework.xcodeproj'
    end

end

With that said, partner test app builds just fine.

The problem which we're facing happens right after partner app launch and is always supported by crash:

... Lots of similar duplication warnings like below comes here ...

objc[58698]: Class GARPseudonymousID is implemented in both /private/var/containers/Bundle/Application/21A274AC-31B1-4AE6-9E3F-1BF720C9B221/TestApp.app/Frameworks/Framework.framework/Framework (0x103d9e0d8) and /private/var/containers/Bundle/Application/21A274AC-31B1-4AE6-9E3F-1BF720C9B221/TestApp.app/TestApp (0x10131e440). One of the two will be used. Which one is undefined. objc[58698]: Class GARPseudonymousIDStore is implemented in both /private/var/containers/Bundle/Application/21A274AC-31B1-4AE6-9E3F-1BF720C9B221/TestApp.app/Frameworks/Framework.framework/Framework (0x103d9e128) and /private/var/containers/Bundle/Application/21A274AC-31B1-4AE6-9E3F-1BF720C9B221/TestApp.app/TestApp (0x10131e490). One of the two will be used. Which one is undefined. F0621 20:33:23.600151 1 registration.h:175] Function with name CallbackPacketCalculator already registered.

*** Check failure stack trace: *** dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/usr/lib/libMTLCapture.dylib dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/usr/lib/libMTLCapture.dylib

What we already know:

  • Project runs fine on a simulator (as far as we tried), but crashes on real device
  • Unlike #43, we do not even have use_frameworks! in Podfile, as was suggested in comment as a workaround.
  • It happens in runtime and only when adding ARCore via CocoaPods and setting pod 'ARCore/AugmentedFaces' both for TestApp and Framework targets.
  • It doesn't make any difference if we're trying to reference Framework API in partner app code (via import Framework and/or calling its API methods) or not, but:
  • When setting pod 'ARCore/AugmentedFaces' for TestApp only, it cannot be accessed inside Framework Swift code in compile time.
  • When setting pod 'ARCore/AugmentedFaces' for Framework only, we get No Such Module: ARCore error via Swift linter right on import Framework line (essentially the place where partner app has an entry to our framework, f.e. in AppDelegate or else).
  • Class N is implemented in both... warning references to all dependencies, but as far as we go only ARCore usage causes crashes and error in log afterwards.
  • ARCore (obviously) works perfectly fine when being added as pod to any simple iOS app project w/o custom modules including it.
  • Removing ARCore pod and references to it completely let us manually test the rest of Framework functionality w/o problems.
  • We're not still 100% sure if class/method duplication issues cause the crash problem, but we're mostly sure it happens when trying to have an ARCore pod inside the both Framework target and app target (or in abstract target on top level). Anyways, getting rid of the pod in any separate Target causes problems mentioned in upper thesises (with current approach).

Any help will be much appreciated!

commented

So, after some headache and playing with pods/configurations, I somehow managed to successfully launch the whole project with following structure, but only by editing scheme to Run in Release configuration:

platform :ios, '11.0'

workspace 'Common.xcworkspace'

abstract_target 'CommonPods' do
    # ... some other common 3rd-party dependencies here ...

    target 'TestApp' do
        project 'TestApp/TestApp.xcodeproj'
    end

    target 'Framework' do
        pod 'ARCore/AugmentedFaces', '~> 1.30.0'
        project 'Framework/Framework.xcodeproj'
    end

end

Seems like a bit poor workaround, but at least custom framework has the access to all desired 3rd-party dependencies and remains fully testable as for now.
Still have no clue why it normally works only for Release configuration runs on physical device.

It seems like your framework includes parts of ARCore, so those parts are getting duplicated. Note that ARCore is statically linked instead of a dynamic library. You need to somehow exclude the dependencies from your binary when you link it.

In general I would highly recommend using a system like CocoaPods or SPM to distribute your SDK, as that will take care of a lot of details for you and make things easier for developers.