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

Release/4.2.4.0.0.0 #2

Merged
merged 23 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
validate-podspec:
runs-on: macos-latest
steps:
- uses: chartboost/chartboost-mediation-ios-actions/adapter-smoke-test@v1
- uses: chartboost/chartboost-ios-adapter-actions/adapter-smoke-test@v1
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
Note the first digit of every adapter version corresponds to the major version of the Chartboost Mediation SDK compatible with that adapter.
Adapters are compatible with any Chartboost Mediation SDK version within that major version.

### {Adapter Version}
- Say something clever.
### 4.2.4.0.0.0
- This version of the adapter has been certified with BidMachine 2.4.0.0.
8 changes: 4 additions & 4 deletions ChartboostMediationAdapterBidMachine.podspec
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Pod::Spec.new do |spec|
spec.name = 'ChartboostMediationAdapterBidMachine'
spec.version = '4.2.3.0.0'
spec.version = '4.2.4.0.0.0'
spec.license = { :type => 'MIT', :file => 'LICENSE.md' }
spec.homepage = 'https://github.com/ChartBoost/chartboost-mediation-ios-adapter-bidmachine'
spec.authors = { 'Chartboost' => 'https://www.chartboost.com/' }
spec.summary = 'Chartboost Mediation iOS SDK Reference adapter.'
spec.summary = 'Chartboost Mediation iOS SDK BidMachine adapter.'
spec.description = 'BidMachine Adapters for mediating through Chartboost Mediation. Supported ad formats: banner, interstitial, rewarded.'

# Source
Expand All @@ -13,7 +13,7 @@ Pod::Spec.new do |spec|
spec.source_files = 'Source/**/*.{swift}'

# Minimum supported versions
spec.swift_version = '5.0'
spec.swift_version = '5.1'
spec.ios.deployment_target = '12.0'

# System frameworks used
Expand All @@ -23,7 +23,7 @@ Pod::Spec.new do |spec|
spec.dependency 'ChartboostMediationSDK', '~> 4.0'

# Partner network SDK and version that this adapter is certified to work with.
spec.dependency 'BidMachine', '2.3.0'
spec.dependency 'BidMachine', '~> 2.4.0.0'
ricealexanderb marked this conversation as resolved.
Show resolved Hide resolved

# Indicates, that if use_frameworks! is specified, the pod should include a static library framework.
spec.static_framework = true
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Chartboost Mediation {Partner} Adapter
# Chartboost Mediation BidMachine Adapter

The Chartboost Mediation {Partner} adapter mediates {Partner} via the Chartboost Mediation SDK.
The Chartboost Mediation BidMachine adapter mediates BidMachine via the Chartboost Mediation SDK.

## Minimum Requirements

| Plugin | Version |
| ------ | ------ |
| Chartboost Mediation SDK | 4.0.0+ |
| Cocoapods | 1.11.3+ |
| iOS | {Partner's minimum iOS version} |
| iOS | 12 |
| Xcode | 14.1+ |

## Integration

In your `Podfile`, add the following entry:
```
pod 'ChartboostMediationAdapter{Partner}'
pod 'ChartboostMediationAdapterBidMachine'
```

## Contributions
Expand All @@ -26,4 +26,4 @@ Refer to our [CONTRIBUTING](CONTRIBUTING.md) file for more information on how to

## License

Refer to our [LICENSE](LICENSE.md) file for more information.
Refer to our [LICENSE](LICENSE.md) file for more information.
155 changes: 155 additions & 0 deletions Source/BidMachineAdapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright 2023-2023 Chartboost, Inc.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

import ChartboostMediationSDK
import Foundation
import UIKit
import BidMachine

final class BidMachineAdapter: PartnerAdapter {
private let SOURCE_ID_KEY = "source_id"

/// The version of the partner SDK.
let partnerSDKVersion = BidMachineSdk.sdkVersion

/// The version of the adapter.
/// It should have either 5 or 6 digits separated by periods, where the first digit is Chartboost Mediation SDK's major version, the last digit is the adapter's build version, and intermediate digits are the partner SDK's version.
/// Format: `<Chartboost Mediation major version>.<Partner major version>.<Partner minor version>.<Partner patch version>.<Partner build version>.<Adapter build version>` where `.<Partner build version>` is optional.
let adapterVersion = "4.2.4.0.0.0"

/// The partner's unique identifier.
let partnerIdentifier = "bidmachine"

/// The human-friendly partner name.
let partnerDisplayName = "BidMachine"

/// Ad storage managed by Chartboost Mediation SDK.
let storage: PartnerAdapterStorage

/// The designated initializer for the adapter.
/// Chartboost Mediation SDK will use this constructor to create instances of conforming types.
/// - parameter storage: An object that exposes storage managed by the Chartboost Mediation SDK to the adapter.
/// It includes a list of created `PartnerAd` instances. You may ignore this parameter if you don't need it.
init(storage: PartnerAdapterStorage) {
self.storage = storage
}

/// Does any setup needed before beginning to load ads.
/// - parameter configuration: Configuration data for the adapter to set up.
/// - parameter completion: Closure to be performed by the adapter when it's done setting up. It should include an error indicating the cause for failure or `nil` if the operation finished successfully.
func setUp(with configuration: PartnerConfiguration, completion: @escaping (Error?) -> Void) {
log(.setUpStarted)

BidMachineSdk.shared.populate {
$0.withTestMode(BidMachineAdapterConfiguration.testMode)
.withLoggingMode(BidMachineAdapterConfiguration.logging)
.withBidLoggingMode(BidMachineAdapterConfiguration.bidLogging)
.withEventLoggingMode(BidMachineAdapterConfiguration.eventLogging)
}

guard let sourceID = configuration.credentials[SOURCE_ID_KEY] as? String else {
let error = error(.initializationFailureInvalidCredentials, description: "The 'source ID' was invalid")
log(.setUpFailed(error))
completion(error)
return
}
// Initialize the SDK
BidMachineSdk.shared.initializeSdk(sourceID)
guard BidMachineSdk.shared.isInitialized == true else {
let error = error(.initializationFailureUnknown)
log(.setUpFailed(error))
completion(error)
return
}
log(.setUpSucceded)
completion(nil)
}

/// Fetches bidding tokens needed for the partner to participate in an auction.
/// - parameter request: Information about the ad load request.
/// - parameter completion: Closure to be performed with the fetched info.
func fetchBidderInformation(request: PreBidRequest, completion: @escaping ([String : String]?) -> Void) {
log(.fetchBidderInfoStarted(request))
guard let token = BidMachineSdk.shared.token else {
let error = error(.prebidFailureInvalidArgument, description: "No bidding token provided by BidMachine SDK")
log(.fetchBidderInfoFailed(request, error: error))
completion(nil)
return
}
log(.fetchBidderInfoSucceeded(request))
completion(["token": token])
}

/// Indicates if GDPR applies or not and the user's GDPR consent status.
/// - parameter applies: `true` if GDPR applies, `false` if not, `nil` if the publisher has not provided this information.
/// - parameter status: One of the `GDPRConsentStatus` values depending on the user's preference.
func setGDPR(applies: Bool?, status: GDPRConsentStatus) {
if let applies = applies {
log(.privacyUpdated(setting: "gdprZone", value: applies))
BidMachineSdk.shared.regulationInfo.populate { $0.withGDPRZone(applies) }
}

// In the case where status == .unknown, we do nothing
if status == .denied {
log(.privacyUpdated(setting: "gdprConsent", value: false))
BidMachineSdk.shared.regulationInfo.populate { $0.withGDPRConsent(false) }
} else if status == .granted {
log(.privacyUpdated(setting: "gdprConsent", value: true))
BidMachineSdk.shared.regulationInfo.populate { $0.withGDPRConsent(true) }
}
}

/// Indicates the CCPA status both as a boolean and as an IAB US privacy string.
/// - parameter hasGivenConsent: A boolean indicating if the user has given consent.
/// - parameter privacyString: An IAB-compliant string indicating the CCPA status.
func setCCPA(hasGivenConsent: Bool, privacyString: String) {
log(.privacyUpdated(setting: "usPrivacyString", value: privacyString))
BidMachineSdk.shared.regulationInfo.populate { $0.withUSPrivacyString(privacyString) }
}

/// Indicates if the user is subject to COPPA or not.
/// - parameter isChildDirected: `true` if the user is subject to COPPA, `false` otherwise.
func setCOPPA(isChildDirected: Bool) {
log(.privacyUpdated(setting: "COPPA", value: isChildDirected))
BidMachineSdk.shared.regulationInfo.populate { $0.withCOPPA(isChildDirected) }
}

/// Creates a new ad object in charge of communicating with a single partner SDK ad instance.
/// Chartboost Mediation SDK calls this method to create a new ad for each new load request. Ad instances are never reused.
/// Chartboost Mediation SDK takes care of storing and disposing of ad instances so you don't need to.
/// `invalidate()` is called on ads before disposing of them in case partners need to perform any custom logic before the object gets destroyed.
/// If, for some reason, a new ad cannot be provided, an error should be thrown.
/// - parameter request: Information about the ad load request.
/// - parameter delegate: The delegate that will receive ad life-cycle notifications.
func makeAd(request: PartnerAdLoadRequest, delegate: PartnerAdDelegate) throws -> PartnerAd {
// Prevent multiple loads for the same partner placement, since the partner SDK cannot handle them.
// Banner loads are allowed so a banner prefetch can happen during auto-refresh.
// ChartboostMediationSDK 4.x does not support loading more than 2 banners with the same placement, and the partner may or may not support it.
guard !storage.ads.contains(where: { $0.request.partnerPlacement == request.partnerPlacement })
|| request.format == .banner
else {
log("Failed to load ad for already loading placement \(request.partnerPlacement)")
throw error(.loadFailureLoadInProgress)
}

switch request.format {
case .interstitial:
return BidMachineAdapterInterstitialAd(adapter: self, request: request, delegate: delegate)
case .rewarded:
return BidMachineAdapterRewardedAd(adapter: self, request: request, delegate: delegate)
case .banner:
return BidMachineAdapterBannerAd(adapter: self, request: request, delegate: delegate)
default:
// Not using the `.adaptiveBanner` case directly to maintain backward compatibility with Chartboost Mediation 4.0
if request.format.rawValue == "adaptive_banner" {
return BidMachineAdapterBannerAd(adapter: self, request: request, delegate: delegate)
} else if request.format.rawValue == "rewarded_interstitial" {
return BidMachineAdapterRewardedAd(adapter: self, request: request, delegate: delegate)
} else {
throw error(.loadFailureUnsupportedAdFormat)
}
}
}
}
37 changes: 37 additions & 0 deletions Source/BidMachineAdapterAd.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2023-2023 Chartboost, Inc.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

import ChartboostMediationSDK
import Foundation

class BidMachineAdapterAd: NSObject {

/// The partner ad view to display inline. E.g. a banner view.
/// Should be nil for full-screen ads.
var inlineView: UIView?

/// The partner adapter that created this ad.
let adapter: PartnerAdapter

/// The ad load request associated to the ad.
/// It should be the one provided on `PartnerAdapter.makeAd(request:delegate:)`.
let request: PartnerAdLoadRequest

/// The partner ad delegate to send ad life-cycle events to.
/// It should be the one provided on `PartnerAdapter.makeAd(request:delegate:)`.
weak var delegate: PartnerAdDelegate?

/// The completion for the ongoing load operation.
var loadCompletion: ((Result<PartnerEventDetails, Error>) -> Void)?

/// The completion for the ongoing show operation.
var showCompletion: ((Result<PartnerEventDetails, Error>) -> Void)?

init(adapter: PartnerAdapter, request: PartnerAdLoadRequest, delegate: PartnerAdDelegate) {
self.adapter = adapter
self.request = request
self.delegate = delegate
}
}
Loading
Loading