Skip to content

Type-safe parsing of JSON response #1127

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
270 changes: 101 additions & 169 deletions PrebidMobile.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion PrebidMobile/AdUnits/Native/NativeAd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public class NativeAd: NSObject, CacheExpiryDelegate {
}

guard let rawBid = PBMORTBBid<PBMORTBBidExt>(jsonDictionary: bidDic, extParser: { extDic in
return PBMORTBBidExt.init(jsonDictionary: extDic)
return PBMCustomModelObjects.instantiate(json: extDic)
}) else {
return nil
}
Expand Down
20 changes: 0 additions & 20 deletions PrebidMobile/BuildFiles/PrebidMobile.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,8 @@ framework module PrebidMobile {
header "PBMRawBidResponse.h"
header "PBMORTBBidResponse.h"
header "PBMORTBBidResponse+Internal.h"
header "PBMORTBBidResponseExt.h"
header "PBMORTBBid.h"
header "PBMORTBBidExt.h"
header "PBMORTBSeatBid.h"
header "PBMORTBBidExtPrebid.h"
header "PBMORTBBidResponseExtPrebid.h"
header "PBMORTBExtPrebidPassthrough.h"
header "PBMORTBAdConfiguration.h"
header "PBMORTBSDKConfiguration.h"
header "PBMORTBBidExtSkadn.h"
header "PBMORTBBidExtSkadnSKOverlay.h"
header "PBMORTBSkadnFidelity.h"
header "PBMORTBExtPrebidEvents.h"
header "PBMORTBMacrosHelper.h"

header "PBMORTBAppContent.h"
Expand All @@ -159,15 +148,6 @@ framework module PrebidMobile {
header "PBMORTBContentSegment.h"
header "PBMORTBNative.h"

// Rewarded
header "PBMORTBRewardedClose.h"
header "PBMORTBRewardedCompletion.h"
header "PBMORTBRewardedCompletionBanner.h"
header "PBMORTBRewardedCompletionVideo.h"
header "PBMORTBRewardedCompletionVideoEndcard.h"
header "PBMORTBRewardedConfiguration.h"
header "PBMORTBRewardedReward.h"

header "NSDictionary+PBMExtensions.h"
header "NSMutableDictionary+PBMExtensions.h"
header "PBMLocationManager.h"
Expand Down
12 changes: 0 additions & 12 deletions PrebidMobile/BuildFiles/PrebidMobileSwiftHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,8 @@

// Bid
#import "PBMORTBBid.h"
#import "PBMORTBBidExt.h"
#import "PBMORTBBidExtPrebid.h"
#import "PBMORTBExtPrebidEvents.h"
#import "PBMORTBAdConfiguration.h"
#import "PBMRawBidResponse.h"

#import "PBMORTBRewardedClose.h"
#import "PBMORTBRewardedCompletion.h"
#import "PBMORTBRewardedCompletionBanner.h"
#import "PBMORTBRewardedCompletionVideo.h"
#import "PBMORTBRewardedCompletionVideoEndcard.h"
#import "PBMORTBRewardedConfiguration.h"
#import "PBMORTBRewardedReward.h"

#import "PBMLocationManager.h"
#import "Log+Extensions.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,12 @@ - (void)handleClickthrough:(NSURL*)url
return;
}
BOOL clickthroughOpened = NO;
PBMJsonDictionary * skadnetProductParameters = [PBMSkadnParametersManager getSkadnProductParametersFor:self.transaction.bid.skadn];

if (skadnetProductParameters) {
__auto_type skadn = self.transaction.bid.skadn;
PBMJsonDictionary * skadnetProductParameters;
if (skadn &&
(skadnetProductParameters = [PBMSkadnParametersManager getSkadnProductParametersFor:skadn]) &&
skadnetProductParameters) {
clickthroughOpened = [self handleProductClickthrough:url
productParams:skadnetProductParameters
onExit:onClickthroughExitBlock];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
 */

#import <Foundation/Foundation.h>
#import "PBMORTBBidExtSkadn.h"

@protocol PBMTransactionDelegate;

Expand Down
18 changes: 9 additions & 9 deletions PrebidMobile/PrebidMobileRendering/Prebid/PBMCore/Bid.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,30 @@ public class Bid: NSObject {

/// Targeting information that needs to be passed to the ad server SDK.
public var targetingInfo: [String : String]? {
bid.ext.prebid?.targeting
bid.ext?.prebid?.targeting?.compactMapValues { $0 as? String }
}

/// Targeting information that needs to be passed to the ad server SDK.
public var meta: [String : Any]? {
bid.ext.prebid?.meta
bid.ext?.prebid?.meta
}

/**
SKAdNetwork parameters about an App Store product.
Used in the StoreKit
*/
public var skadn: PBMORTBBidExtSkadn? {
return bid.ext.skadn
return bid.ext?.skadn
}

/// Prebid ad format
public var adFormat: AdFormat? {
AdFormat.allCases.filter { $0.stringEquivalent == bid.ext.prebid?.type }.first
AdFormat.allCases.filter { $0.stringEquivalent == bid.ext?.prebid?.type }.first
}

/// Prebid video ad configuration
public var videoAdConfiguration: PBMORTBAdConfiguration? {
bid.ext.prebid?.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.adConfiguration
bid.ext?.prebid?.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.adConfiguration
}

/// Preffered plugin renderer name
Expand All @@ -100,12 +100,12 @@ public class Bid: NSObject {
// Need to be removed when ext.prebid.passthrough will be available.
#if DEBUG
public var testVideoAdConfiguration: PBMORTBAdConfiguration? {
bid.ext.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.adConfiguration
bid.ext?.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.adConfiguration
}
#endif

public var rewardedConfig: PBMORTBRewardedConfiguration? {
bid.ext.prebid?.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.rewardedConfiguration
bid.ext?.prebid?.passthrough?.filter { $0.type == "prebidmobilesdk" }.first?.rewardedConfiguration
}

/// Returns YES if this bid is intented for display.
Expand All @@ -129,7 +129,7 @@ public class Bid: NSObject {
}

public var events: PBMORTBExtPrebidEvents? {
bid.ext.prebid?.events
bid.ext?.prebid?.events
}

public private(set) var bid: PBMORTBBid<PBMORTBBidExt>
Expand All @@ -148,7 +148,7 @@ extension Bid {
guard let bidDic = Utils.shared.getDictionaryFromString(bidString),
let rawBid = PBMORTBBid<PBMORTBBidExt>(
jsonDictionary: bidDic,
extParser: { PBMORTBBidExt(jsonDictionary: $0)}
extParser: { PBMCustomModelObjects.instantiate(json: $0) }
) else { return nil }

return Bid(bid: rawBid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ public class BidResponse: NSObject {
let rawResponse = PBMORTBBidResponse<PBMORTBBidResponseExt, NSDictionary, PBMORTBBidExt>(
jsonDictionary: jsonDictionary as! [String : Any],
extParser: { extDic in
return PBMORTBBidResponseExt(jsonDictionary: extDic)
return PBMCustomModelObjects.instantiate(json: extDic)
},
seatBidExtParser: { extDic in
return extDic as NSDictionary
},
bidExtParser: { extDic in
return PBMORTBBidExt(jsonDictionary: extDic)
return PBMCustomModelObjects.instantiate(json: extDic)
})

self.init(rawBidResponse: rawResponse)
Expand Down Expand Up @@ -86,7 +86,7 @@ public class BidResponse: NSObject {
self.winningBid = winningBid
self.allBids = allBids
self.targetingInfo = targetingInfo.count > 0 ? targetingInfo : nil
tmaxrequest = rawBidResponse.ext.tmaxrequest
tmaxrequest = rawBidResponse.ext?.tmaxrequest
self.ext = rawBidResponse.ext
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//
// Copyright 2018-2025 Prebid.org, Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//


import Foundation

public class PBMCustomModelObjects: NSObject {

private static var lock: UnsafeMutablePointer<pthread_rwlock_t> = {
let lock = UnsafeMutablePointer<pthread_rwlock_t>.allocate(capacity: 1)
lock.initialize(to: pthread_rwlock_t())
pthread_rwlock_init(lock, nil)

return lock
}()

private static var _customTypes = [(baseType: PBMORTBAbstract.Type, customType: PBMORTBAbstract.Type)]()
static func getCustomType<T: PBMORTBAbstract>(_ type: T.Type) -> T.Type {
pthread_rwlock_rdlock(lock)
defer { pthread_rwlock_unlock(lock) }

return _customTypes.first { $0.baseType == type }?.customType as? T.Type ?? type
}

static func setCustomType<T: PBMORTBAbstract>(baseType: T.Type, customType: T.Type) {
pthread_rwlock_wrlock(lock)
defer { pthread_rwlock_unlock(lock) }

_customTypes.removeAll { $0.baseType == baseType }
if customType != baseType {
_customTypes.append((baseType: baseType, customType: customType))
}
}

static func instantiate<T: PBMORTBAbstract>(json: [String : Any]) -> T? {
getCustomType(T.self).init(jsonDictionary: json)
}

public static func unregisterCustomType(_ type: PBMORTBAbstract.Type) {
pthread_rwlock_wrlock(lock)
defer { pthread_rwlock_unlock(lock) }

_customTypes.removeAll { type == $0.baseType || type == $0.customType }
}

public static func registerCustomType(_ type: PBMORTBAdConfiguration.Type) {
setCustomType(baseType: PBMORTBAdConfiguration.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExt.Type) {
setCustomType(baseType: PBMORTBBidExt.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExtPrebid.Type) {
setCustomType(baseType: PBMORTBBidExtPrebid.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExtPrebidCache.Type) {
setCustomType(baseType: PBMORTBBidExtPrebidCache.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExtPrebidCacheBids.Type) {
setCustomType(baseType: PBMORTBBidExtPrebidCacheBids.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExtSkadn.Type) {
setCustomType(baseType: PBMORTBBidExtSkadn.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidExtSkadnSKOverlay.Type) {
setCustomType(baseType: PBMORTBBidExtSkadnSKOverlay.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidResponseExt.Type) {
setCustomType(baseType: PBMORTBBidResponseExt.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBBidResponseExtPrebid.Type) {
setCustomType(baseType: PBMORTBBidResponseExtPrebid.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBExtPrebidEvents.Type) {
setCustomType(baseType: PBMORTBExtPrebidEvents.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBExtPrebidPassthrough.Type) {
setCustomType(baseType: PBMORTBExtPrebidPassthrough.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedClose.Type) {
setCustomType(baseType: PBMORTBRewardedClose.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedCompletion.Type) {
setCustomType(baseType: PBMORTBRewardedCompletion.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedCompletionBanner.Type) {
setCustomType(baseType: PBMORTBRewardedCompletionBanner.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedCompletionVideo.Type) {
setCustomType(baseType: PBMORTBRewardedCompletionVideo.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedCompletionVideoEndcard.Type) {
setCustomType(baseType: PBMORTBRewardedCompletionVideoEndcard.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedConfiguration.Type) {
setCustomType(baseType: PBMORTBRewardedConfiguration.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBRewardedReward.Type) {
setCustomType(baseType: PBMORTBRewardedReward.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBSDKConfiguration.Type) {
setCustomType(baseType: PBMORTBSDKConfiguration.self, customType: type)
}

public static func registerCustomType(_ type: PBMORTBSkadnFidelity.Type) {
setCustomType(baseType: PBMORTBSkadnFidelity.self, customType: type)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN

@interface PBMORTBAbstractResponse<__covariant ExtType> : PBMORTBAbstract

@property (nonatomic, strong) ExtType ext;
@property (nonatomic, strong, nullable) ExtType ext;

@end

Expand Down

This file was deleted.

Loading