How to create a shared Admob banner for multiple views? - ios

I am buildung my very first application with Admob banners in Xcode.
My apps uses multiple UIViews connect via NavigationController and currently I am requesting a new ad for every UIView.
That is what I already got for every UIViewController:
import GoogleMobileAds
class ViewController: UIViewController {
#IBOutlet weak var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
bannerView.adUnitID = "ca-app-pub-281379xxxxx/64134xxxxx"
bannerView.rootViewController = self
bannerView.loadRequest(GADRequest())
}
}
How can I implement a "shared" banner for all views which gets managed from a separate class or by the AppDelegate. (All of my views got an GADBannerView at the bottom already.)
I never really worked with delegate methods before, because coding is just hobby from me and I am learning like: Try & Error. But at this point my skills aren't good enough to realize this.
I would appreciate any kind of help :-). Thank you!

Related

messageCollectionView in MessageKit not being recognized

I'm new to Xcode development and very new to MessageKit. I'm currently following an iOS Academy video to get the messaging section of my app working (Great series of videos by the way).
I have installed the MessageKit cocoa pod (and reinstalled it like 3 times to make sure I did it right) but yet, I can't seem to use the messagesCollectionView property.
I know it exists because first, the tutorial uses it, and second, after further investigation, ITS THE FIRST ATTRIBUTE OF THE VIEW CONTROLLER
open class MessagesViewController: UIViewController,
UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecognizerDelegate {
/// The `MessagesCollectionView` managed by the messages view controller object.
open var messagesCollectionView = MessagesCollectionView()
/// The `InputBarAccessoryView` used as the `inputAccessoryView` in the view controller.
open lazy var messageInputBar = InputBarAccessoryView()
when I start typing out "messagesCollectionView" there is no autocomplete and I get an error that says that it cannot be found in scope. Here is my view controller
class ChatViewController: MessagesViewController {
let currentUser = Sender(senderId: "self",displayName: "Yianni Zavaliagkos")
let otherUser = Sender(senderId: "other",displayName: "Ezra Taylor")
var messages: [MessageType] = []
override func viewDidLoad() {
super.viewDidLoad()
title = "Chat"
messages.append(Message(sender: currentUser,
messageId: "1",
sentDate: Date().addingTimeInterval(-86400),
kind: .text("Hello World")))
messages.append(Message(sender: otherUser,
messageId: "2",
sentDate: Date().addingTimeInterval(-70000),
kind: .text("How is it going")))
//Errors on these next couple lines
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messagesLayoutDelegate = self
messagesCollectionView.messagesDisplayDelegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}
}
and yes, I have implemented the MessegesDataSource and Layout and Display Delegates as well.
My first guess is that I installed the cocoa pod somehow incorrectly but I've tried everything and was hoping to be blessed by the StackOverflow Gods with an easy solution to this frustrating problem. Thanks!
You need to reload your collection, so put: messagesCollectionView.reloadData() to your viewDidLoad method. It works for me

Is there a difference between creating a view object explicitly in the scope of the class vs the loadView function?

I was following a tutorial from a book and want to move ahead without reading the code in the book to see what I would come up with on my own based on the instructions. My code is a little different by creating the MKMapView object globally outside of the loadView() function however the book creates the MKMapView object inside the loadView() function. Both processes work so I want to know if there is much of a difference or preference among the iOS development community?
Thank you in advance.
My code:
import Foundation
import UIKit
import MapKit
class MapViewController: UIViewController {
var mapView: MKMapView = MKMapView()
override func loadView() {
view = mapView
}
}
The book's code:
import Foundation
import UIKit
import MapKit
class MapViewController: UIViewController {
var mapView: MKMapView!
override func loadView() {
mapView = MKMapView()
view = mapView
}
}
The difference is in the first case the map view is created right when the view controller is initialized.
In the second case, the view is lazily created when the viewController.view is first accessed.
I'd recommend the second approach since that's in line with Apple's recommendation.

Why my indicator view is not showing?

Using swift3 with xcode8
Below is my viewconroller.swift
class ViewController: UIViewController {
#IBOutlet weak var YahooWebview: UIWebView!
#IBOutlet weak var activity: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let YURL = URL(string: "http://www.yahoo.com")
let YURLRequest = URLRequest(url: YURL!)
YahooWebview.loadRequest(YURLRequest)
}
}
func webViewDidStartLoad(YahooWebview: UIWebView) {
activity.startAnimating()
}
func webViewDidFinishLoad(YahooWebview: UIWebView) {
print("show indicator")
activity.stopAnimating()
}
Why my indicator is not showing when webview is loading?
I can not even see string "show indicator" from my log in Xcode.
You need to set your class as the delegate of UIWebView as
YahooWebview.delegate = self
Check my answer to get details regarding delegates and delegation pattern.
Note from apple developer: In apps that run in iOS 8 and later, use the
WKWebView class instead of using UIWebView. Additionally, consider setting the WKPreferences property javaScriptEnabled to false if you render files that are not supposed to run JavaScript.
There can be two problems as mentioned in comments.
Both can be solved in your Stroyboard/xib file.
Your UIActivityIndicatorView is may be hidden behind UIWebView. Just change the position of the view so that it comes above in the view heirarchy.
You may not have set delegate property of UIWebview class as your ViewController. Right click on webview and check. This needs to be set as you are animating the activity indicator view inside delegate methods.

Memory leak when including Eureka form within table view

I have an application using Swift3 and Eureka Forms 2.0.0. I really love Eureka forms, but my app is leaking memory like crazy and I'm trying to pick it apart to see what's wrong. On the most basic level, I have a custom view controller that contains a table view (I have some other elements around the form that I need to control separately) that I want to tie into a Eureka form. However, even with the most basic possible case, I'm still seeing memory leaks. Here's the view controller I'm testing with:
class TestViewController: FormViewController {
#IBOutlet weak var formTableView: UITableView!
#IBOutlet var mainText: UILabel!
var titleString : String?
override func viewDidLoad() {
NSLog("viewDidLoad")
super.tableView = formTableView
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Just loading this and moving back and forth to another view results in the following leak report in Instruments:
Any advice on this would be much appreciated.
Thanks,
Alex

Swift: About Protocols and Delegation pattern

i want to ask that how the protocols and delegation patterns functions in Swift.
I have an application that let me try the google ad sdk on iOS platform. But i'm missing something and confused about how the methods works.
I have some codes like these;
import UIKit
import GoogleMobileAds
class ViewController: UIViewController, GADInterstitialDelegate {
#IBOutlet weak var bannerView: GADBannerView!
let request = GADRequest()
var interstitial: GADInterstitial!
#IBOutlet weak var mylbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
bannerView.adUnitID = "xxx"
bannerView.rootViewController = self
bannerView.loadRequest(self.request)
interstitial = createAndLoadInterstitial()
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "xxx")
interstitial.delegate = self
interstitial.loadRequest(self.request)
return interstitial
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
interstitial = createAndLoadInterstitial()
mylbl.text = "No ad"
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
mylbl.text = "received ad"
}
#IBAction func touched(sender: AnyObject) {
if interstitial.isReady
{
interstitial.presentFromRootViewController(self)
}
else
{
mylbl.text = "Not Ready!"
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
For the code above, i'm aware of that the protocols blueprints of methods and properties to adopt a class or struct or enum. The methods or properties defined in the protocol should be implemented on the class that adopted by the related delegate.
I want to ask that and cofused point: OK the method which is named "interstitialDidDismissScreen" inherited from the delegate "GADInsterstitialDelegate" but how the method handled by pressing the close button of the interstitial ad. Where the engineers of Google implemented and how they succeed this behavior. Thanks for your help.
Good hacks,
The button handling is taking place inside the GADInterstitial class. When they setup the class they probably have some internal methods that handle all the ad interaction, and then using the delegate methods they send back to your class the info you need to know to keep your UI managed. By implementing the delegate and its methods you've said I want to use something that your class does, and then I want to also handle all the feedback from that class. If you were to make your own class and implement a protocol and delegate you could do whatever you want inside your class and then pass back just a sliver of info to the class' delegate. An example would be a barcode reading class. I don't care how the barcode gets read, I just want to know the code, so I could set my calling class to be the delegate of the barcode reading class, and when the barcode is read I would receive the barcode back inside of a barcode delegate method.
The wording of your question is garbled and hard to figure out.
A protocol is basically a contract. It says that objets that conform to the protocol promise to provide the properties, and respond to the methods that the protocol defines.
When you say
someObject.delegate = self
You are passing a pointer to yourself to the other object. This is like giving somebody your phone number and saying "Please run these errands for me. If you have any questions, call me at this number. Also please call me when the errands are done."
Since the other object knows that it's delegate conforms to a specific protocol, it knows what messages it can send over the phone (what messages it can send to the delegate)
I suspect the methods interstitialDidReceiveAd(ad: GADInterstitial!) and interstitialDidDismissScreen(ad: GADInterstitial!) are delegate methods.
When the interstitial object needs to send messages to it's delegate, it calls these methods.

Resources