Trying to integrate Facebook audience Network ad placements into my SwiftUI project.
The tutorial published by Facebook assumes the use of UIKit only!
With zero experience in UIKit, need your kind help to enable me to integrate the follwing lines of code into my ContentView as a SwiftUI view:
//Add a UIView element to the main View element and name it to adContainer.
//Now, in your View Controller header file (or Swift file, if you are a Swift user),
//import FBAudienceNetwork, declare conformance to the FBAdViewDelegate protocol,
//and add an instance variable for the ad unit
import UIKit
import FBAudienceNetwork
class ViewController: UIViewController, FBAdViewDelegate {
#IBOutlet private var adContainer: UIView!
private var adView: FBAdView?
}
//Add the code below to viewDidLoad; Create a new instance of FBAdView and add it to the view.
//FBAdView is a subclass of UIView. You can add it to your view hierarchy just like any other view.
override func viewDidLoad() {
super.viewDidLoad()
// Instantiate an AdView object.
// NOTE: the placement ID will eventually identify this as your app, you can ignore while you
// are testing and replace it later when you have signed up.
// While you are using this temporary code you will only get test ads and if you release
// your code like this to the App Store your users will not receive ads (you will get a 'No Fill' error).
let adView = FBAdView(placementID: "YOUR_PLACEMENT_ID", adSize: kFBAdSizeHeight50Banner, rootViewController: self)
adView.frame = CGRect(x: 0, y: 0, width: 320, height: 250)
adView.delegate = self
adView.loadAd()
self.adView = adView
}
//Optionally, you can add the following functions to handle the cases
//where the ad is closed or when the user clicks on it:
func adViewDidClick(_ adView: FBAdView) {
print("Ad was clicked.")
}
func adViewDidFinishHandlingClick(_ adView: FBAdView) {
print("Ad did finish click handling.")
}
func adViewWillLogImpression(_ adView: FBAdView) {
print("Ad impression is being captured.")
}
//Add and implement the following two delegate functions in your
//View Controller to handle ad loading failures:
func adView(_ adView: FBAdView, didFailWithError error: Error) {
print("Ad failed to load with error: \(error.localizedDescription)")
}
func adViewDidLoad(_ adView: FBAdView) {
print("Ad was loaded and ready to be displayed")
showAd()
}
private func showAd() {
guard let adView = adView, adView.isAdValid else {
return
}
adContainer.addSubview(adView)
}
Your help would be tremendously appreciated would be
Related
I'm sorry if the title is confusing, i'm kind of new to the whole thingy.
I'm trying to integrate PassBase ID verification to my app, which is built using SwiftUI, their documentation offers instructions using Swift and view Controllers.
My question is, is there a way to insert the Swift code part into my SwiftUI view?
The code example from their Documentation:
import Passbase
import UIKit
class ViewController: UIViewController, PassbaseDelegate {
override func viewDidLoad() {
super.viewDidLoad()
PassbaseSDK.delegate = self
// Optional - You can prefill the email to skip that step.
Passbase.prefillUserEmail = "testuser#yourproject.com"
let button = PassbaseButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
self.view.addSubview(button)
}
func onFinish(identityAccessKey: String) {
print("onFinish with identityAccessKey \(identityAccessKey)")
}
func onSubmitted(identityAccessKey: String) {
print("onSubmitted with identityAccessKey \(identityAccessKey)")
}
func onError(errorCode: String) {
print("onError with code \(errorCode)")
}
func onStart() {
print("onStart")
}
}
As i understand this part of code should create a button in a VC.
My goal is to add this button with functionality to my SwiftUI view.
Full Documentation: https://docs.passbase.com/ios#general
Thank you all in advance for the help!
The basic strategy is to use a View that represents the content you want to bring in from a UIViewController. Your View is going to conform to UIViewCotrollerRepresentable and use the functions of that protocol to create and manage the UIKit content.
The UIViewControllerRepresentable documentation is here
And, as was commented on your original post by vadian, there is A tutorial with sample code
With the sample code above, I would rename "ViewController" to be something like PassBaseViewController or PBViewController, then you would create a View that derives from UIViewControllerRepresentable
You end up with a file called PBViewController.swift that has your code from above:
import Passbase
import UIKit
class PBViewController: UIViewController, PassbaseDelegate {
override func viewDidLoad() {
super.viewDidLoad()
PassbaseSDK.delegate = self
// Optional - You can prefill the email to skip that step.
Passbase.prefillUserEmail = "testuser#yourproject.com"
let button = PassbaseButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
self.view.addSubview(button)
}
... and the rest of the code from your question here ...
Then (probably in another file, but not necessarily) you could create the SwiftUIView that uses that view controller:
struct PassBaseView : UIViewControllerRepresentable {
typealias UIViewControllerType = PBViewController
func makeUIViewController(context: Context) -> PBViewController {
return PBViewController()
}
func updateUIViewController(_ uiViewController: PBViewController, context: Context) {
/* code here to make changes to the view controller if necessary when this view is updated*/
}
}
I am making an app for iPad with multitasking enabled and right now I am trying to implement an Admob banner.
There is an article about doing that in case of multitasking enabled (https://developers.google.com/admob/ios/multiscene?hl=ru) but all code there is written in Objective-C when I'm using Swift.
I tried to translate it but I have no idea how to do that for the piece of code below. What is "requestInitialized"? What it should do and how to write it in Swift?
If anyone has a full code for successful implementing an Admob banner in multitasking app, please help me with it
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!_requestInitialized) {
[self loadInterstitial];
_requestInitialized = YES;
}
}
For SwiftUI you can add this :
request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
GoogleAdmob does offer a quick-start here that does show you Swift.. I will also provide some instructions.
Make sure you have the GoogleMobileAds pod added to your project and have the correct plist setup.
In your didFinishLaunchingWithOptions in your AppDelegate.swift add the following:
GADMobileAds.sharedInstance().start(completionHandler: nil)
Drag and drop a normal UIView into your storyboard, give it a width of 320 and a height of 50. Then you can change the class of the view to a GADBannerView. Then use the code below and make sure your IBOutlet is connected.
import UIKit
import GoogleMobileAds
class ViewController: UIViewController, GADBannerViewDelegate {
#IBOutlet weak var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
bannerView.adUnitID = "ca-app-pub-3940256099942544/6300978111" // Test Banner ID, replace with your ID here.
bannerView.rootViewController = self
bannerView.load(GADRequest())
bannerView.delegate = self
}
// MARK: - GADBannerViewDelegate
func adViewDidReceiveAd(_ bannerView: GADBannerView) {
print("Received Ad")
}
func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
print(error)
}
}
How can I create the types of view that slide up from the bottom of the screen as pictured below? Is this a built-in view type or something custom?
The screen shots are from Wunderlist and The Hit List iOS apps respectively.
Just had a look at The Hit List there. Seems like they're just animating a view up from the bottom.
I'd go about this by creating a UIView, let's call it slidingView. You can do it in your existing storyboard or create a new .xib file for it. Then, when you call your viewDidLoad for the view controller that this slidingView will be contained in, move the slidingView view off screen and animate it in whenever you want.
Example:
import UIKit
class ViewController: UIViewController {
private struct Constants {
static let animationDuration: TimeInterval = 0.3
static let marginFromTop: CGFloat = 32.0
}
#IBOutlet private weak var slidingView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
moveSlidingViewOffScreen()
}
// MARK: - Actions
#IBAction func buttonTap(_ sender: UIButton) {
UIView.animate(withDuration: Constants.animationDuration) {
self.slidingView.frame.origin.y = Constants.marginFromTop
}
}
// MARK: - Private functions
private func setupSlidingViewOffScreen() {
slidingView.frame.origin.y = view.frame.height
}
}
I'm trying to implement CVCalendar with my project. I have everything in, but at the end it asks for me to connect outlets. Here is an image of the instructions:
Click here for image
I have no idea what to do as I am new to swift and xcode development. Here is the link to the github page: https://github.com/CVCalendar/CVCalendar
Any help would be appreciated, thanks!
I assume you've extended CVCalendarMenuViewDelegate and CVCalendarViewDelegate on your ViewController and implemented the delegate methods required for CVCalendar such as presentationMode and firstWeekday.
class ViewController: UIViewController {
...
}
extension ViewController: CVCalendarMenuViewDelegate {
...
}
extension ViewController: CVCalendarViewDelegate {
func presentationMode() -> CalendarMode {
return CalendarMode.monthView
}
func firstWeekday() -> Weekday {
return Weekday.monday
}
}
The last thing to do is to connect CVCalendar's menuView and calendarView objects to this class. This means that whenever an action occurs with a calendarView or menuView object the action knows to be routed to the delegate methods of your ViewController because you've attached it as an outlet.
This can be done in InterfaceBuilder by holding the control key and dragging from the menuView and calendarView to the top of the scene and then choosing the delegate to connect to, as shown in this image.
Connecting an outlet
This can also be done programmatically in your ViewController's viewDidLoad method.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
calendarView.delegate = self
menuView.delegate = self
}
I have a banner view and want to have a custom close button. My problem is that the button is displayed before the ad is loaded and displayed.
class RootVC: UIViewController, GADBannerViewDelegate {
var googleAdBanner: GADBannerView!
var googleBannerCloseBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
googleAdBanner = GADBannerView(frame:CGRectMake(0,0,100,100))
googleAdBanner.center = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2)
googleAdBanner.adUnitID = "xx"
googleAdBanner.rootViewController = self
googleAdBanner.loadRequest(GADRequest())
adViewWillPresentScreen(googleAdBanner)
googleAdBanner.delegate = self
self.view.addSubview(googleAdBanner)
}
func adViewWillPresentScreen(bannerView: GADBannerView!) {
googleBannerCloseBtn = UIButton(frame: CGRectMake( 5 , 5, 25, 25))
googleBannerCloseBtn.backgroundColor = UIColor.clearColor()
googleBannerCloseBtn.setImage(UIImage(named: "closeBtn"), forState: .Normal)
googleBannerCloseBtn.setTitle("Click Me", forState: UIControlState.Normal)
googleBannerCloseBtn.addTarget(self, action: #selector(RootVC.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
googleBannerCloseBtn.tag = 1
googleAdBanner.addSubview(googleBannerCloseBtn)
}
How do I present the button only when the GADBannerView has loaded an ad and is presented?
Same behavior with adViewDidReceiveAd. The button is visible, even if the GADBannerView is "invisible" because there is no ad loaded currently.
Screens as requested. As you see, the button, that is a subView of the GADBannerView is displayed before the ad itself is displayed.
I've commented out alot of the logic in this example. The only thing that I didn't mention was that you will need to create two Ad Unit ID's. One for your GADBannerView and one for your GADInterstitial on AdMob.com.
import UIKit
import GoogleMobileAds // Import AdMob
class ViewController: UIViewController, GADBannerViewDelegate, GADInterstitialDelegate { // Include our delegates
// Create our ads
var banner = GADBannerView(adSize: kGADAdSizeBanner) // kGADAdSizeBanner is a default banner size
var interstitial = GADInterstitial(adUnitID: "YourInterstitialAdUnitID")
override func viewDidLoad() {
super.viewDidLoad()
// View has loaded so lets setup our ads initially
setupAds()
}
// MARK: - Setup Ads
func setupAds() {
// Setup our banner ad
banner.adUnitID = "YourBannerAdUnitID"
banner.rootViewController = self
banner.delegate = self
// Hide our banner initially until it loads an ad
// Not doing this is why your close button was visible
// GADBannerView's with no ad are essentially "clear", not hidden
banner.alpha = 0.0
banner.loadRequest(GADRequest())
// Position banner on bottom of view
banner.frame = CGRect(x: 0.0,
y: view.frame.height - banner.frame.height,
width: view.frame.width,
height: banner.frame.height)
// Create your button here and add it as a subview to banner
// banner.addSubview(closeButton)
view.addSubview(banner)
// Setup our interstitial ad initially
interstitial.delegate = self
interstitial.loadRequest(GADRequest())
}
// MARK: - Load Interstitial Ad
func loadFullScreenAd() {
// GADInterstitial's are single use. You have to create a new GADInterstitial for each presentation
// So, if you'd like to show more than one GADInterstitial in your apps session we need this
// This func will be used to create a new GADInterstitial after one has been displayed and dismissed
interstitial = GADInterstitial(adUnitID: "YourInterstitialAdUnitID")
interstitial.delegate = self
interstitial.loadRequest(GADRequest())
}
// MARK: - Show Interstitial Ad
func showFullScreenAd() {
// Call this function when you want to present the interstitial ad
// ie. game over, transition to another vc, etc...
// Make sure you give atleast a few seconds for this ad to load before atempting to present it
// For example, don't try to present this ad in viewDidAppear
// Check if the interstitial ad is loaded before trying to present it
if interstitial.isReady {
interstitial.presentFromRootViewController(self)
}
}
// MARK: - Close Button Action
func closeButtonAction() {
// This is where we will handle your close button that you've added to your GADBannerView
// You can handle this two ways and it depends on what you'd like to do
// If you don't want to show the banner ad again during the entire app session you would hide the banner
// This way even if we change the alpha values in our delegate methods the banner will remain hidden
banner.hidden = true
// Another way you can handle the close button would be to hide the banner until another banner ad is loaded
// I believe the refresh rate for banner ads is 45-60 seconds. You can customize the refresh time on AdMob.com
// So, this way if the user tapped the close button the banner would fade out
// But, when another banner ad is loaded the banner would fade back in because of the code in our adViewDidReceiveAd delegate method
UIView.animateWithDuration(0.2) {
self.banner.alpha = 0.0
}
/////* Choose which way you'd like to handle the close button and remove the code for the other */////
}
// MARK: - GADBannerView Delegate Methods
func adViewDidReceiveAd(bannerView: GADBannerView!) {
print("adViewDidReceiveAd")
// We received an ad so lets show it
// You could even fade in the banner if you'd like
UIView.animateWithDuration(0.2) {
self.banner.alpha = 1.0
}
}
func adView(bannerView: GADBannerView!, didFailToReceiveAdWithError error: GADRequestError!) {
print("banner didFailToReceiveAdWithError: \(error)")
// We received an error when trying to load our GADBannerView
// Lets hide it because we don't have an ad
// You could also fade this out if you'd like
UIView.animateWithDuration(0.2) {
self.banner.alpha = 0.0
}
}
// MARK: - GADInterstitial Delegate Methods
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("interstitialDidReceiveAd")
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
print("interstitialWillPresentScreen")
// If you needed to pause anything in your app this would be the place to do it
// ie. sounds, game state, etc...
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("interstitialDidDismissScreen")
// The GADInterstitial has been shown and dismissed by the user
// Lets load another one for the next time we want to show a GADInterstitial
loadFullScreenAd()
// If you paused anything in the interstitialWillPresentScreen delegate method this is where you would resume it
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print("interstitial didFailToReceiveAdWithError: \(error)")
}
}
Also, if you plan on presenting the GADInterstitial often in your application I'd recommend disabling video ads on AdMob.com for that Ad Unit ID. AdMob interstitial video ads disable the close button for 5 seconds, kind of like the skip button on YouTube, and will aggravate your users instantaneously. If you're rarely showing the GADInterstitial then I'd leave the video ads enabled.