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

Swift UIAlertView cleanup #137

Open
wants to merge 1 commit 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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import GoogleMobileAds
import UIKit

/// Custom native ad view struct that defines the custom ad template asset keys as type properties.
struct MySimpleNativeAdViewTypeProperties {
enum MySimpleNativeAdViewTypeProperties {

/// The headline asset key.
static let MySimpleNativeAdViewHeadlineKey = "Headline"
Expand All @@ -35,6 +35,7 @@ class MySimpleNativeAdView: UIView {

/// Weak references to this ad's asset views.
@IBOutlet weak var headlineView: UILabel!

@IBOutlet weak var mainPlaceholder: UIView!
@IBOutlet weak var captionView: UILabel!

Expand All @@ -45,25 +46,34 @@ class MySimpleNativeAdView: UIView {
super.awakeFromNib()

// Enable clicks on the main image.
mainPlaceholder.addGestureRecognizer(UITapGestureRecognizer(target: self,
mainPlaceholder.addGestureRecognizer(
UITapGestureRecognizer(
target: self,
action: #selector(MySimpleNativeAdView.performClickOnMainImage(_:))))
mainPlaceholder.isUserInteractionEnabled = true
}

@objc func performClickOnMainImage(_ sender: UIImage!) {
customNativeAd.performClickOnAsset(
withKey: MySimpleNativeAdViewTypeProperties.MySimpleNativeAdViewMainImageKey)
withKey: MySimpleNativeAdViewTypeProperties.MySimpleNativeAdViewMainImageKey)
}

/// Populates the ad view with the custom native ad object.
func populate(withCustomNativeAd customNativeAd: GADNativeCustomTemplateAd) {
self.customNativeAd = customNativeAd
// The custom click handler closure overrides the normal click action defined by the ad.
customNativeAd.customClickHandler = { assetID in
let alertView = UIAlertView(title: "Custom Click", message: "You just clicked on the image!",
delegate: self, cancelButtonTitle: "OK")
alertView.alertViewStyle = .default
alertView.show()
let alert = UIAlertController(
title: "Custom Click",
message: "You just clicked on the image!",
preferredStyle: .alert)
let alertAction = UIAlertAction(
title: "OK",
style: .cancel,
handler: nil)
alert.addAction(alertAction)
UIApplication.shared.keyWindow?.rootViewController?.present(
alert, animated: true, completion: nil)
}

// Populate the custom native ad assets.
Expand All @@ -78,9 +88,10 @@ class MySimpleNativeAdView: UIView {

/// This custom native ad also has a both a video and image associated with it. We'll use the
/// video asset if available, and otherwise fallback to the image asset.
private func mainView(forCustomNativeAd customNativeAd:GADNativeCustomTemplateAd) -> UIView {
private func mainView(forCustomNativeAd customNativeAd: GADNativeCustomTemplateAd) -> UIView {
if customNativeAd.videoController.hasVideoContent(),
let mediaView = customNativeAd.mediaView {
let mediaView = customNativeAd.mediaView
{
return mediaView
} else {
let imageKey = MySimpleNativeAdViewTypeProperties.MySimpleNativeAdViewMainImageKey
Expand All @@ -89,21 +100,23 @@ class MySimpleNativeAdView: UIView {
}
}

private func updateMainView(_ mainView:UIView) {
private func updateMainView(_ mainView: UIView) {
// Remove all the media placeholder's subviews.
for subview: UIView in mainPlaceholder.subviews {
for subview:UIView in mainPlaceholder.subviews {
subview.removeFromSuperview()
}
mainPlaceholder.addSubview(mainView)
// Size the media view to fill our container size.
mainView.translatesAutoresizingMaskIntoConstraints = false
let viewDictionary: [AnyHashable: Any] = ["mainView":mainView]
mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
withVisualFormat: "H:|[mainView]|", options: [], metrics: nil,
views: viewDictionary as? [String : Any] ?? [String : Any]()))
mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
withVisualFormat: "V:|[mainView]|", options: [], metrics: nil,
views: viewDictionary as? [String : Any] ?? [String : Any]()))
let viewDictionary: [AnyHashable: Any] = ["mainView": mainView]
mainPlaceholder.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "H:|[mainView]|", options: [], metrics: nil,
views: viewDictionary as? [String: Any] ?? [String: Any]()))
mainPlaceholder.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "V:|[mainView]|", options: [], metrics: nil,
views: viewDictionary as? [String: Any] ?? [String: Any]()))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ class ViewController: UIViewController {
// Layout constraints for positioning the native ad view to stretch the entire width and height
// of the nativeAdPlaceholder.
let viewDictionary = ["_nativeAdView": nativeAdView!]
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[_nativeAdView]|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary))
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[_nativeAdView]|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "H:|[_nativeAdView]|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary)
)
self.view.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "V:|[_nativeAdView]|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: viewDictionary)
)
}

// MARK: - Actions
Expand All @@ -88,16 +94,23 @@ class ViewController: UIViewController {
}

if adTypes.isEmpty {
let alertView = UIAlertView(title: "Alert", message: "At least one ad format must be " +
"selected to refresh the ad.", delegate: self, cancelButtonTitle: "OK")
alertView.alertViewStyle = .default
alertView.show()
let alert = UIAlertController(
title: "Alert",
message: "At least one ad format must be selected to refresh the ad.",
preferredStyle: .alert)
let alertAction = UIAlertAction(
title: "OK",
style: .cancel,
handler: nil)
alert.addAction(alertAction)
self.present(alert, animated: true, completion: nil)
} else {
refreshAdButton.isEnabled = false
let videoOptions = GADVideoOptions()
videoOptions.startMuted = startMutedSwitch.isOn
adLoader = GADAdLoader(adUnitID: adUnitID, rootViewController: self,
adTypes: adTypes, options: [videoOptions])
adLoader = GADAdLoader(
adUnitID: adUnitID, rootViewController: self,
adTypes: adTypes, options: [videoOptions])
adLoader.delegate = self
adLoader.load(GADRequest())
videoStatusLabel.text = ""
Expand Down Expand Up @@ -133,24 +146,23 @@ class ViewController: UIViewController {
// By acting as the delegate to the GADVideoController, this ViewController receives messages
// about events in the video lifecycle.
videoStatusLabel.text = "Ad contains a video asset."
}
else {
} else {
videoStatusLabel.text = "Ad does not contain a video."
}
}

}

// MARK: - GADAdLoaderDelegate
extension ViewController : GADAdLoaderDelegate {
extension ViewController: GADAdLoaderDelegate {
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: GADRequestError) {
print("\(adLoader) failed with error: \(error.localizedDescription)")
refreshAdButton.isEnabled = true
}
}

// MARK: - GADUnifiedNativeAdLoaderDelegate
extension ViewController : GADUnifiedNativeAdLoaderDelegate {
extension ViewController: GADUnifiedNativeAdLoaderDelegate {

func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADUnifiedNativeAd) {
print("Received unified native ad: \(nativeAd)")
Expand All @@ -174,9 +186,9 @@ extension ViewController : GADUnifiedNativeAdLoaderDelegate {
// Some native ads will include a video asset, while others do not. Apps can use the
// GADVideoController's hasVideoContent property to determine if one is present, and adjust their
// UI accordingly.
let hasVideoContent = nativeAd.mediaContent.hasVideoContent // Update the ViewController for video content.
let hasVideoContent = nativeAd.mediaContent.hasVideoContent // Update the ViewController for video content.
updateVideoStatusLabel(hasVideoContent: hasVideoContent)
if (hasVideoContent) {
if hasVideoContent {
// By acting as the delegate to the GADVideoController, this ViewController receives messages
// about events in the video lifecycle.
nativeAd.mediaContent.videoController.delegate = self
Expand All @@ -185,13 +197,14 @@ extension ViewController : GADUnifiedNativeAdLoaderDelegate {
// This app uses a fixed width for the GADMediaView and changes its height to match the aspect
// ratio of the media it displays.
if let mediaView = nativeAdView.mediaView, nativeAd.mediaContent.aspectRatio > 0 {
let heightConstraint = NSLayoutConstraint(item: mediaView,
attribute: .height,
relatedBy: .equal,
toItem: mediaView,
attribute: .width,
multiplier: CGFloat(1 / nativeAd.mediaContent.aspectRatio),
constant: 0)
let heightConstraint = NSLayoutConstraint(
item: mediaView,
attribute: .height,
relatedBy: .equal,
toItem: mediaView,
attribute: .width,
multiplier: CGFloat(1 / nativeAd.mediaContent.aspectRatio),
constant: 0)
heightConstraint.isActive = true
}

Expand All @@ -206,7 +219,8 @@ extension ViewController : GADUnifiedNativeAdLoaderDelegate {
(nativeAdView.iconView as? UIImageView)?.image = nativeAd.icon?.image
nativeAdView.iconView?.isHidden = nativeAd.icon == nil

(nativeAdView.starRatingView as? UIImageView)?.image = imageOfStars(fromStarRating:nativeAd.starRating)
(nativeAdView.starRatingView as? UIImageView)?.image = imageOfStars(
fromStarRating: nativeAd.starRating)
nativeAdView.starRatingView?.isHidden = nativeAd.starRating == nil

(nativeAdView.storeView as? UILabel)?.text = nativeAd.store
Expand All @@ -223,46 +237,48 @@ extension ViewController : GADUnifiedNativeAdLoaderDelegate {
}
}


// MARK: - GADNativeCustomTemplateAdLoaderDelegate
extension ViewController : GADNativeCustomTemplateAdLoaderDelegate {
extension ViewController: GADNativeCustomTemplateAdLoaderDelegate {
func nativeCustomTemplateIDs(for adLoader: GADAdLoader) -> [String] {
return [ nativeCustomTemplateId ]
return [nativeCustomTemplateId]
}

func adLoader(_ adLoader: GADAdLoader,
didReceive nativeCustomTemplateAd: GADNativeCustomTemplateAd) {
func adLoader(
_ adLoader: GADAdLoader,
didReceive nativeCustomTemplateAd: GADNativeCustomTemplateAd
) {
print("Received custom native ad: \(nativeCustomTemplateAd)")
refreshAdButton.isEnabled = true
// Create and place the ad in the view hierarchy.
let customNativeAdView = Bundle.main.loadNibNamed(
"SimpleCustomNativeAdView", owner: nil, options: nil)!.first as! MySimpleNativeAdView
let customNativeAdView =
Bundle.main.loadNibNamed(
"SimpleCustomNativeAdView", owner: nil, options: nil)!.first as! MySimpleNativeAdView
setAdView(customNativeAdView)

let hasVideoContent = nativeCustomTemplateAd.videoController.hasVideoContent()
// Update the ViewController for video content.
updateVideoStatusLabel(hasVideoContent: hasVideoContent)
if (hasVideoContent) {
if hasVideoContent {
nativeCustomTemplateAd.videoController.delegate = self
}
// Populate the custom native ad view with the custom native ad assets.
customNativeAdView.populate(withCustomNativeAd:nativeCustomTemplateAd)
customNativeAdView.populate(withCustomNativeAd: nativeCustomTemplateAd)
// Impressions for custom template format must be manually tracked. If this is not called,
// videos will also not be played.
nativeCustomTemplateAd.recordImpression()
}
}

// MARK: - GADVideoControllerDelegate implementation
extension ViewController : GADVideoControllerDelegate {
extension ViewController: GADVideoControllerDelegate {

func videoControllerDidEndVideoPlayback(_ videoController: GADVideoController) {
videoStatusLabel.text = "Video playback has ended."
}
}

// MARK: - GADUnifiedNativeAdDelegate implementation
extension ViewController : GADUnifiedNativeAdDelegate {
extension ViewController: GADUnifiedNativeAdDelegate {

func nativeAdDidRecordClick(_ nativeAd: GADUnifiedNativeAd) {
print("\(#function) called")
Expand Down
4 changes: 2 additions & 2 deletions Swift/admanager/AdManagerCustomRenderingExample/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ DEPENDENCIES:
- Google-Mobile-Ads-SDK

SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
https://github.com/CocoaPods/Specs:
- Google-Mobile-Ads-SDK
- GoogleAppMeasurement
- GoogleUtilities
Expand All @@ -47,4 +47,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: f7c41e035c07771ca0e5c5c7964b9164b2b0bc7d

COCOAPODS: 1.8.0
COCOAPODS: 1.8.4
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
TargetAttributes = {
84FEE90E1B0D65A8006C8148 = {
CreatedOnToolsVersion = 6.2;

LastSwiftMigration = 0900;
};
};
Expand Down
Loading