Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prebid Linking to SPM by building it to XCFramework #961

Open
mrbodich opened this issue Mar 7, 2024 · 15 comments
Open

Prebid Linking to SPM by building it to XCFramework #961

mrbodich opened this issue Mar 7, 2024 · 15 comments
Assignees
Labels

Comments

@mrbodich
Copy link

mrbodich commented Mar 7, 2024

Considering the fact this package does not support the Swift Package Manager, I have tried to build it using scripts/buildPrebidMobile.sh.
I have modified the shell script a bit so it is executed without errors (removed eval wrapper for the last xcodebuild, changed arch for the simulator to arm64 for the M processor).
As an output, I get 4 frameworks.
PrebidMobile — I was able to link it in the Package.swift (to my ads module package) using these

dependencies: [
    .....
    .byName(name: "XCPrebidMobile"),
],
.binaryTarget(name: "XCPrebidMobile", path: "Frameworks/XCPrebidMobile.xcframework"),

from this suggestion (but skipping .c and .h files linking): https://developer.apple.com/forums/thread/651069?answerId=769888022#769888022

This method worked for XCPrebidMobile. I can build and run the app, tried to call Prebid.shared.description and runtime did not crash.
But the same for XCPrebidMobileAdMobAdapters makes runtime crash on the app launch. I will attach the crash logs in the end.
As I see, the problem is caused by FBLPromises (PromisesObjC) which is not found.
Maybe it is possible to figure out how to solve this error and it should allow to link other 3 frameworks?
It would be a really huuuuge trouble if we will have to somehow link this package using Cocoapods in the modular project with cross-dependencies of SPM modules, and even implemented macros.

Also attaching the slightly modified build script which worked for me. Rows 80, 89-94.
buildPrebidMobile.txt

Thank you.

dyld[64900]: Library not loaded: @rpath/FBLPromises.framework/FBLPromises
  Referenced from: <7D61BE76-8DE4-31A3-9B8C-E028A8557C73> /Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PrebidMobileAdMobAdapters.framework/PrebidMobileAdMobAdapters
  Reason: tried: '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/FBLPromises.framework/FBLPromises' (no such file), '/usr/lib/swift/FBLPromises.framework/FBLPromises' (no such file, not in dyld cache), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PrebidMobileAdMobAdapters.framework/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/FBLPromises.framework/FBLPromises' (no such file)Library not loaded: @rpath/FBLPromises.framework/FBLPromises
  Referenced from: <687B6486-B735-3323-9493-7CFB31177A33> /Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PrebidMobileGAMEventHandlers.framework/PrebidMobileGAMEventHandlers
  Reason: tried: '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/FBLPromises.framework/FBLPromises' (no such file), '/usr/lib/swift/FBLPromises.framework/FBLPromises' (no such file, not in dyld cache), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PrebidMobileGAMEventHandlers.framework/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/Xcode/DerivedData/AppName-ayeugevkpvqwahcbzwglotgbprxl/Build/Products/Debug-iphonesimulator/PackageFrameworks/FBLPromises.framework/FBLPromises' (no such file), '/Users/username/Library/Developer/CoreSimulator/Devices/42BC06C6-9E2A-4B22-9D7E-BC4968B38C5C/data/Containers/Bundle/Application/3012C1C4-ACE6-4EB4-8DFB-5803EB494EB3/AppName.app/Frameworks/FBLPromises.framework/FBLPromises' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/FBLPromises.framework/FBLPromises' (no such file)
@mrbodich
Copy link
Author

mrbodich commented Mar 7, 2024

UPD:

I was able to launch the app without crash using tips from here Alamofire/Alamofire#3051
I have replaced all 6 occurrences of use_frameworks! by use_modular_headers! and the app starts and works now with all 4 Prebid XCFrameworks linked in the Package.swift.

Maybe you can use this info to do some modifications and put it to your docs, in the SPM section.

@ankit-thanekar007
Copy link
Contributor

Hi @mrbodich , Can you share the Package.swift file that you created for this, Mine is something like this, currently I see the same issue as you dyld[64900]: Library not loaded: @rpath/FBLPromises.framework/FBLPromises. Also how did you link the 4 frameworks in your app ?

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "PrebidSPM",
    platforms: [
        .iOS(.v13)
        ],
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "PrebidMobile",
            targets: ["XCPrebidMobile", "XCPrebidMobileAdMobAdapters", "XCPrebidMobileGAMEventHandlers", "XCPrebidMobileMAXAdapters"]
        )
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages which this package depends on.
    
        .binaryTarget(
            name: "XCPrebidMobile",
            path: "artifacts/XCPrebidMobile.xcframework"
        ),
        .binaryTarget(
            name: "XCPrebidMobileAdMobAdapters",
            path: "artifacts/XCPrebidMobileAdMobAdapters.xcframework"
        ),
        .binaryTarget(
            name: "XCPrebidMobileGAMEventHandlers",
            path: "artifacts/XCPrebidMobileGAMEventHandlers.xcframework"
        ),
        .binaryTarget(
            name: "XCPrebidMobileMAXAdapters",
            path: "artifacts/XCPrebidMobileMAXAdapters.xcframework"
        ),
    ]
)

@YuriyVelichkoPI
Copy link
Contributor

Hi @ankit-thanekar007 , @mrbodich short note about the 4 frameworks. Most probably, you don't need all of them.

The main one is PrebidMobile - the Prebid SDK itself. All others are connectors to the primary ad server SDK. And they should be used only with particular integration of Rendering API. If your primary ad server is GAM, you don't need any if these dependencies in your app. As a result, you won't need to manage the issue with third-party libraries like FBLPromises because Prebid SDK itself doesn't use any dependencies.

@mrbodich
Copy link
Author

mrbodich commented Mar 13, 2024

Hi @YuriyVelichkoPI. I have AdMob and want to use Prebid with the Ad Mediation. Don't I need XCPrebidMobileAdMobAdapters? I believe I would need it.

Your documentation says

Adapaters Integration
Prebid SDK is integrated into AdMob setup thru custom adapters. To integrate Prebid Adapters into your app, add the following line to your Podfile:

pod 'PrebidMobileAdMobAdapters'

@mrbodich
Copy link
Author

mrbodich commented Mar 13, 2024

@ankit-thanekar007 You have to make a target with each framework first, and only after that use this target in the product library.
Maybe... I did not check your version. Possibly it should work in yours, but my config works.

PS: @ankit-thanekar007 Please read my second message where I have described how to deal with this error Library not loaded by using use_modular_headers!

let packageMock = Package(
    name: "AdsPackage",
    platforms: [
        .iOS(.v15)
    ],
    products: [
        // Products define the executables and libraries a package produces, making them visible to other packages.
        .library(
            name: "AdsPackage",
            targets: ["AdsPackage"]
        ),
    ],
    dependencies: [
        .package(url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", .upToNextMajor(from: "10.13.0")),
    ],
    targets: [
        .target(
            name: "AdsPackage",
            dependencies: [
                .product(name: "GoogleMobileAds", package: "swift-package-manager-google-mobile-ads"),
                .byName(name: "XCPrebidMobile"),
                .byName(name: "XCPrebidMobileAdMobAdapters"),
                .byName(name: "XCPrebidMobileGAMEventHandlers"),
                .byName(name: "XCPrebidMobileMAXAdapters"),
            ],
            swiftSettings: [.enableUpcomingFeature("StrictConcurrency"), .unsafeFlags(["-Xfrontend", "-strict-concurrency=complete"])]
        ),
        .binaryTarget(name: "XCPrebidMobile", path: "Frameworks/XCPrebidMobile.xcframework"),
        .binaryTarget(name: "XCPrebidMobileAdMobAdapters", path: "Frameworks/XCPrebidMobileAdMobAdapters.xcframework"),
        .binaryTarget(name: "XCPrebidMobileGAMEventHandlers", path: "Frameworks/XCPrebidMobileGAMEventHandlers.xcframework"),
        .binaryTarget(name: "XCPrebidMobileMAXAdapters", path: "Frameworks/XCPrebidMobileMAXAdapters.xcframework"),
    ]
)

@YuriyVelichkoPI
Copy link
Contributor

Hi @YuriyVelichkoPI. I have AdMob and want to use Prebid with the Ad Mediation. Don't I need XCPrebidMobileAdMobAdapters? I believe I would need it.

Your documentation says

Adapaters Integration
Prebid SDK is integrated into AdMob setup thru custom adapters. To integrate Prebid Adapters into your app, add the following line to your Podfile:
pod 'PrebidMobileAdMobAdapters'

you will definitely need AdMobAdapter, but you won't need the other two - GAMEventHandlers and AppLovinMAXAdapters. I see in the @ankit-thanekar007 message that he added all frameworks and trying to say that some of them can be redundant.

@mrbodich
Copy link
Author

@YuriyVelichkoPI I understand that I don't need other two right at this moment. But not sure it's really a trouble that I've made a comprehensive example for you as the package developers, to have the best example with all frameworks linked))
I also have to be sure, that once I will ever need any of other two, I will be able to add them, and not re-write the half of the app because did not try to link them in advance. So, I am still sure I did not do any redundant actions.

Anyway, the topic is how to link your package fully with the SMP, let's avoid the specific app logic discussion pleeeeease))) I just wanted to help you with the info I have found spending my time.

@YuriyVelichkoPI
Copy link
Contributor

@mrbodich sorry for taking your time, go ahead.

@ankit-thanekar007
Copy link
Contributor

@mrbodich @YuriyVelichkoPI Thanks for the inputs. I'll test the changes and revert back to you guys !

@chwo
Copy link

chwo commented Mar 28, 2024

@YuriyVelichkoPI Can you as the framework vendor please consider providing the XCFramework as a ZIP archive directly. E.g. by uploading it somewhere publicly accessible like the assets of the GitHub release. 🙏

That way, us framework consumers can use the framework directly in SPM by accessing it as a remote (URL-based) binary target without any additional overhead on our side. Additionally, this would also work around the issue that the framework is not available in SPM anymore since version 2.0.0 (#640).

@joshwalker
Copy link

Any update on getting pre-compiled XCFrameworks. I've followed the steps to do it myself, but now with the latest update, there is a new version of Ruby required, and it is another hassle to upgrade my system. Vs just updating the version of the package.

@YuriyVelichkoPI
Copy link
Contributor

Hi @chwo, unfortunately, I'm not a framework vendor. Let me ping @alexsavelyev and @mmullin to bump this issue into the committee meeting and prioritize it in the backlog.

@YuriyVelichkoPI
Copy link
Contributor

It looks feasible to support SPM by publishing the frameworks on GitHub into Assets.

Here is the API how to upload the assets: https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#update-a-release-asset
Here is an article with examples of SPM using artifacts from GitHub: https://forums.swift.org/t/spm-binary-dependency-in-private-github-release/52514

All the info provided above should be considered in supporting SPM as well.

cc: @alexsavelyev, @mmullin, @jsligh

@mrbodich
Copy link
Author

mrbodich commented Aug 5, 2024

Hello guys @YuriyVelichkoPI @ankit-thanekar007 . Some time passed, checking the base...
I see this issue was closed, but not sure I can understand if SMP was implemented.
As I understood, the plan was to pre-compile the framework, and publish SPM package maybe even under another repository, as some vendors do.

Please check, exactly same Google does here, they pre-build a binary and created a repo with SPM support.
https://github.com/googleads/swift-package-manager-google-mobile-ads.git

Can you please tell me the status of this issue, and if you have plans to make SMP support in this really simple way?

PS: I was able to build all 4 submodules with v2.2.3 and import them to the parent package, and build the project, and call some parameters from each object created from one of 4 respective package.
Ruby 3.1.1, Xcode 15.3, Swift 5.10
The only modification to the build script is removed eval wrapper and replaced x86_64 with arm64 for the simulator, removed export PATH for ruby.

@YuriyVelichkoPI
Copy link
Contributor

Hi @mrbodich! Yes, there is an intent to support SPM via rebuild binaries. Unfortunately, there are no resources or volunteers to do it.

So, for now, the task is still in the backlog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Ready for Dev
Development

No branches or pull requests

6 participants