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

[iOS][AdManager][Banner] An ad is not rendered properly #189

Merged
merged 13 commits into from
Jun 18, 2019
Merged
4 changes: 2 additions & 2 deletions example/Swift/PrebidDemo/PrebidDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HR94J6TSB3;
INFOPLIST_FILE = PrebidDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -634,7 +634,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HR94J6TSB3;
INFOPLIST_FILE = PrebidDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
6 changes: 6 additions & 0 deletions example/Swift/PrebidDemo/PrebidDemo/BannerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ class BannerController: UIViewController, GADBannerViewDelegate, MPAdViewDelegat

func adViewDidReceiveAd(_ bannerView: GADBannerView) {
print("adViewDidReceiveAd")

Utils.shared.findPrebidCreativeSize(bannerView) { (size) in
if let bannerView = bannerView as? DFPBannerView, let size = size {
bannerView.resize(GADAdSizeFromCGSize(size))
}
}
}

func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
Expand Down
155 changes: 155 additions & 0 deletions example/Swift/PrebidDemo/PrebidDemoTests/PrebidDemoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,161 @@ class PrebidDemoTests: XCTestCase, GADBannerViewDelegate, GADInterstitialDelegat
waitForExpectations(timeout: timeoutForRequest, handler: nil)

}



let transactionFailRepeatCount = 5
let screenshotDelaySeconds = 3.0
let transactionFailDelaySeconds = 3.0

//30x250 -> 728x90
func testRubiconDFPBannerResizeSanityAppCheckTest() {

class BannerViewDelegate: NSObject, GADBannerViewDelegate {
let outer: PrebidDemoTests
var loadSuccesfulExpectation: XCTestExpectation
var prebidbBannerAdUnit: BannerAdUnit
var first: Int
var second: Int

init(outer: PrebidDemoTests, loadSuccesfulExpectation: XCTestExpectation, prebidbBannerAdUnit: BannerAdUnit, first: inout Int, second: inout Int) {

self.outer = outer
self.loadSuccesfulExpectation = loadSuccesfulExpectation
self.prebidbBannerAdUnit = prebidbBannerAdUnit
self.first = first
self.second = second
}

func adViewDidReceiveAd(_ bannerView: GADBannerView) {
Log.debug("AdManager adViewDidReceiveAd")

Utils.shared.findPrebidCreativeSize(bannerView) { (size) in
if let bannerView = bannerView as? DFPBannerView, let size = size {
bannerView.resize(GADAdSizeFromCGSize(size))

let bannerViewFrame = bannerView.frame;
let bannerViewSize = CGSize(width: bannerViewFrame.width, height: bannerViewFrame.height)

XCTAssertEqual(bannerViewSize, size)

//Wait to make screenshot
XCTWaiter.wait(for: [XCTestExpectation(description: "wait")], timeout: self.outer.screenshotDelaySeconds)

self.outer.makeScreenShot()
}

self.outer.onResult(isSuccess: true, prebidbBannerAdUnit: self.prebidbBannerAdUnit, loadSuccesfulExpectation: self.loadSuccesfulExpectation, first: &self.first, second: &self.second)
}

}

func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
Log.warn("AdManager adView:didFailToReceiveAdWithError: \(error.localizedDescription)")

self.outer.onResult(isSuccess: false, prebidbBannerAdUnit: self.prebidbBannerAdUnit, loadSuccesfulExpectation: loadSuccesfulExpectation, first: &self.first, second: &self.second)
}
}

var firstTransactionCount = 0
var secondTransactionCount = 0

let loadSuccesfulExpectation: XCTestExpectation = expectation(description: "load succesful")
loadSuccesfulExpectation.expectedFulfillmentCount = 2
loadSuccesfulExpectation.assertForOverFulfill = false

//Logic
setUpAppRubicon()
timeoutForRequest = 30.0

let prebidbBannerAdUnit = BannerAdUnit(configId: Constants.PBS_CONFIG_ID_300x250_RUBICON, size: CGSize(width: 300, height: 250))

let delegare = BannerViewDelegate(outer:self, loadSuccesfulExpectation: loadSuccesfulExpectation, prebidbBannerAdUnit: prebidbBannerAdUnit, first: &firstTransactionCount, second: &secondTransactionCount)

let gamBannerView = DFPBannerView()
gamBannerView.validAdSizes = [
NSValueFromGADAdSize(kGADAdSizeMediumRectangle),
NSValueFromGADAdSize(GADAdSizeFromCGSize(CGSize(width: 728, height: 90))),
]

gamBannerView.adUnitID = "/5300653/test_adunit_pavliuchyk_300x250_puc_ucTagData_prebid-server.rubiconproject.com"

gamBannerView.rootViewController = viewController
gamBannerView.delegate = delegare
gamBannerView.backgroundColor = .red

viewController?.view.addSubview(gamBannerView)


let request: DFPRequest = DFPRequest()
prebidbBannerAdUnit.fetchDemand(adObject: request) { (resultCode: ResultCode) in
if resultCode == ResultCode.prebidDemandFetchSuccess {

gamBannerView.load(request)
} else {
Log.warn("ERROR bannerUnit.fetchDemand resultCode: \(resultCode.name())")
self.onResult(isSuccess: false, prebidbBannerAdUnit: prebidbBannerAdUnit, loadSuccesfulExpectation: loadSuccesfulExpectation, first: &firstTransactionCount, second: &secondTransactionCount)
}
}

wait(for: [loadSuccesfulExpectation], timeout: 100)
}

func onResult(isSuccess: Bool, prebidbBannerAdUnit: BannerAdUnit, loadSuccesfulExpectation: XCTestExpectation, first: inout Int, second: inout Int) {
if isSuccess {

if first != -1 {
first = -1

prebidbBannerAdUnit.adSizes = [CGSize(width: 728, height: 90)]
prebidbBannerAdUnit.refreshDemand()

} else if second != -1 {
second = -1
}

loadSuccesfulExpectation.fulfill()

} else {
//time-out
XCTWaiter.wait(for: [XCTestExpectation(description: "wait")], timeout: self.transactionFailDelaySeconds)

if first != -1 {
if first > self.transactionFailRepeatCount - 2 {
XCTFail("first Transaction Count == 5")
loadSuccesfulExpectation.fulfill()
loadSuccesfulExpectation.fulfill()

} else {
Log.warn("first transaction repear#\(first)")
first += 1
prebidbBannerAdUnit.refreshDemand()
}
} else if second != -1 {
if second > self.transactionFailRepeatCount - 2 {
XCTFail("second Transaction Count == 5")
loadSuccesfulExpectation.fulfill()
loadSuccesfulExpectation.fulfill()
} else {
Log.warn("second transaction repear#\(second)")
second += 1
prebidbBannerAdUnit.refreshDemand()
}
} else {
XCTFail("Unexpected")
}

}
}

func makeScreenShot() {
// Taking screenshot after test
let screenshot = XCUIScreen.main.screenshot()
let fullScreenshotAttachment = XCTAttachment(screenshot: screenshot)
fullScreenshotAttachment.lifetime = .keepAlways

add(fullScreenshotAttachment)
}

func testDFPBannerWithoutAutoRefresh() {
var fetchDemandCount = 0
Expand Down
4 changes: 2 additions & 2 deletions src/PrebidMobile/PrebidMobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@
EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES;
INFOPLIST_FILE = PrebidMobile/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -681,7 +681,7 @@
EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES;
INFOPLIST_FILE = PrebidMobile/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
151 changes: 151 additions & 0 deletions src/PrebidMobile/PrebidMobile/AdUnits/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

import Foundation
import WebKit

public class Utils: NSObject {

Expand Down Expand Up @@ -89,6 +90,156 @@ public class Utils: NSObject {

}
}

public func findPrebidCreativeSize(_ adView: UIView, completion: @escaping (CGSize?) -> Void) {

let view = self.recursivelyFindWebView(adView) { (subView) -> Bool in
return subView is WKWebView || subView is UIWebView
}

if let wkWebView = view as? WKWebView {
Log.debug("subView is WKWebView")
self.findSizeInWebViewAsync(wkWebView: wkWebView, completion: completion)

} else if let uiWebView = view as? UIWebView {
Log.debug("subView is UIWebView")
self.findSizeInWebViewAsync(uiWebView: uiWebView, completion: completion)
} else {
Log.warn("subView doesn't include WebView")
}

}

func runResizeCompletion(size: CGSize?, completion: @escaping (CGSize?) -> Void) {

Log.debug("size:\(size)")
completion(size)
}

func recursivelyFindWebView(_ view: UIView, closure:(UIView) -> Bool) -> UIView? {
for subview in view.subviews {

if closure(subview) {
return subview
}

if let result = recursivelyFindWebView(subview, closure: closure) {
return result
}
}

return nil
}

func findSizeInWebViewAsync(wkWebView: WKWebView, completion: @escaping (CGSize?) -> Void) {

wkWebView.evaluateJavaScript("document.body.innerHTML", completionHandler: { (value: Any!, error: Error!) -> Void in

if error != nil {
Log.warn("error:\(error.localizedDescription)")
return
}

let wkResult = self.findSizeInJavaScript(jsCode: value as? String)

self.runResizeCompletion(size: wkResult, completion: completion)
})

}

func findSizeInWebViewAsync(uiWebView: UIWebView, completion: @escaping (CGSize?) -> Void) {

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {

if uiWebView.isLoading {
self.findSizeInWebViewAsync(uiWebView: uiWebView, completion: completion)
} else {

let content = uiWebView.stringByEvaluatingJavaScript(from: "document.body.innerHTML")

let uiResult = self.findSizeInJavaScript(jsCode: content)
self.runResizeCompletion(size: uiResult, completion: completion)
}
}

}

func findSizeInJavaScript(jsCode: String?) -> CGSize? {
guard let jsCode = jsCode else {
Log.warn("jsCode is nil")
return nil
}

guard let hbSizeKeyValue = findHbSizeKeyValue(in: jsCode) else {
Log.warn("HbSizeKeyValue is nil")
return nil
}

guard let hbSizeValue = findHbSizeValue(in: hbSizeKeyValue) else {
Log.warn("HbSizeValue is nil")
return nil
}

return stringToCGSize(hbSizeValue)
}

func findHbSizeKeyValue(in text: String) -> String?{
return matchAndCheck(regex: "hb_size\\W+[0-9]+x[0-9]+", text: text)
}

func findHbSizeValue(in hbSizeKeyValue: String) -> String?{
return matchAndCheck(regex: "[0-9]+x[0-9]+", text: hbSizeKeyValue)
}

func matchAndCheck(regex: String, text: String) -> String?{
let matched = matches(for: regex, in: text)

if matched.isEmpty {
return nil
}

let firstResult = matched[0]

return firstResult
}

func matches(for regex: String, in text: String) -> [String] {

do {
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
return results.map {
String(text[Range($0.range, in: text)!])
}
} catch let error {
Log.warn("invalid regex: \(error.localizedDescription)")
return []
}
}

func stringToCGSize(_ size: String) -> CGSize? {

let sizeArr = size.split{$0 == "x"}.map(String.init)
guard sizeArr.count == 2 else {
Log.warn("\(size) has a wrong format")
return nil
}

let nsNumberWidth = NumberFormatter().number(from: sizeArr[0])
let nsNumberHeight = NumberFormatter().number(from: sizeArr[1])

guard let numberWidth = nsNumberWidth, let numberHeight = nsNumberHeight else {
Log.warn("\(size) can not be converted to CGSize")
return nil
}

let width = CGFloat(truncating: numberWidth)
let height = CGFloat(truncating: numberHeight)

let gcSize = CGSize(width: width, height: height)

return gcSize
}

@objc func validateAndAttachKeywords (adObject: AnyObject, bidResponse: BidResponse) {

Expand Down
Loading