Trying to subclass GADRewardBasedVideoAdDelegate on Swift - ios

I am trying to create a singleton class, subclass of GADRewardBasedVideoAdDelegate. Something like this:
import Foundation
import GoogleMobileAds
class MyAdsManager : GADRewardBasedVideoAdDelegate {
private let id : String = "MY_ADMOB_ID"
private var selector : (()->Void)?
static let instance: MyAdsManager = {
return MyAdsManager()
}()
class func getInstance() -> MyAdsManager {
return instance
}
private init() {
loadVideo()
}
//more methods
}
The error message is:
Type 'MyAdsManager' does not conform to protocol 'NSObjectProtocol'
I am not sure if I am doing this correctly, but implementing NSObjectProtocol is not something I am looking for...
Thank you in advance people.

Replace
class MyAdsManager : GADRewardBasedVideoAdDelegate
with
class MyAdsManager : NSObject, GADRewardBasedVideoAdDelegate
Reason
GADRewardBasedVideoAdDelegate inherits from NSObjectProtocol so you have to implement all methods listed in NSObjectProtocol and since these methods are implemented inside NSObject subclasses so it does the job for you

Related

Accessing value from one class using protocol in other class IOS swift

Hello I am trying to access the variables and function from the class which is following one protocol ios swift in other class please let me know what i am doing wrong.
First image is of protocol and class which is declaring variables and functions and second image is of accessing the protocol, force unwrapping it and accessing values,functions.
code of protocol and first class
import Foundation
import CoreLocation
import UIKit
import Contacts
protocol FilterSessionPresenter: class {
var numberOfSection: Int {get}
func viewLoaded()
func filterTapped()
}
class FilterSessionPresenterImplementation : FilterSessionPresenter {
init() {
print("runnninggg...")
}
func viewLoaded() {
print("Hello")}
func filterTapped() {
print("Hello")}
var numberOfSection: Int {
return 200}
}
code for accessing class
import UIKit
class FilterSessionVC: UIViewController {
var presenter : FilterSessionPresenter!
override func viewDidLoad() {
print(presenter.numberOfSection)
}
}

Protocol extensions where Self is generic

I have a BaseViewController that is defined this way:
open class BaseViewController<ViewModel: ViewModelType, View: BaseView>: UIViewController { ... }
I'm trying to write an extension for a protocol that has a default behaviour for all my BaseViewControllers. Something like this:
protocol MyProtocol {
func doStuff()
}
extension MyProtocol where Self: BaseViewController<BaseViewModel, BaseView> {
func doStuff() { ... }
}
However. If I only tells that the generic types are the BaseViewModel and BaseView it doesn't works for my subclasses, even though those are the most lower level classes used here.
How can I write my protocol extension in a way it will works for all my BaseViewController classes?

Swift Class Pointer as? Class Protocol?

I have a class, lets call it SomeClass. Instances of SomeClass have an optional pointer to SomeOtherClass. In this way, instances of SomeClass can be instantiated, given a pointer to SomeOtherClass (or a subclass of SomeOtherClass), and then this pointer can be used to dynamically create instances of this SomeOtherClass belonging to SomeClass. Eg;
class SomeClass {
var classPointer: SomeOtherClass.Type?
}
class SomeOtherClass {
}
So far so good. Now, I have a protocol - lets call it SomeProtocol - that I want SomeOtherClass to conform to. This protocol has class functions in it:
protocol SomeProtocol {
static func someClassFunction()
}
extension SomeOtherClass : SomeProtocol {
class func someClassFunction() {
print("I am a class function being executed on SomeOtherClass")
}
}
As expected, I can then call this protocol class function on SomeOtherClass like so:
SomeOtherClass.someClassFunction() // Prints "I am a class function being executed on SomeOtherClass"
Here is the troublesome part. I want to dynamically determine if an instance of SomeClass' classPointer conforms to SomeProtocol, and if so execute the class function on it. So, I try to cast the pointer using as?:
// Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
let someInstance = SomeClass()
someInstance.classPointer = SomeOtherClass.self
// Check if the instance's classPointer class conforms to the SomeProtocol protocol
if let conformingClass = someInstance.classPointer as? SomeProtocol {
// If so, execute the class function in SomeProtocol on the instance's classPointer
conformingClass.someClassFunction() // Build fails "Static member someClassFunction cannot be used on instance of type SomeProtocol"
}
And the build fails with the error "Static member of someClassFunction cannot be used on instance of type SomeProtocol".
Is there a way to accomplish what I'm attempting? Currently if this doesn't work I can only think of these alternatives (none are preferable and they're all rather hacky):
Switch to objective c.
Switch the protocol to use instance functions instead, then instantiate a temporary instance of SomeClass' classPointer and message it with any necessary functions, then release the instance.
For completeness, here is all of the code together that can be pasted into a Playground (it won't build due to the error I mentioned though):
class SomeClass {
var classPointer: SomeOtherClass.Type?
}
class SomeOtherClass {
}
protocol SomeProtocol {
static func someClassFunction()
}
extension SomeOtherClass : SomeProtocol {
class func someClassFunction() {
print("I am a class function being executed on SomeOtherClass")
}
}
// Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
let someInstance = SomeClass()
someInstance.classPointer = SomeOtherClass.self
// Check if the instance's classPointer class conforms to the SomeProtocol protocol
if let conformingClass = someInstance.classPointer as? SomeProtocol {
// If so, execute the class function in SomeProtocol on the instance's classPointer
conformingClass.someClassFunction() // Build fails "Static member someClassFunction cannot be used on instance of type SomeProtocol"
}
Thanks for any help you can provide,
- Adam
Ahah! As usual, as soon as I make the SO post, I figure out the answer.
For those wondering, you must cast the classPointer as the protocol's Type, not as the protocol itself. The line:
if let conformingClass = someInstance.classPointer as? SomeProtocol {
Needs to be changed to:
if let conformingClass = someInstance.classPointer as? SomeProtocol.Type {
And you'll then be able to message conformingClass with the class functions declared in SomeProtocol. The complete working code is:
class SomeClass {
var classPointer: SomeOtherClass.Type?
}
class SomeOtherClass {
}
protocol SomeProtocol {
static func someClassFunction()
}
extension SomeOtherClass : SomeProtocol {
class func someClassFunction() {
print("I am a class function being executed on SomeOtherClass")
}
}
// Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
let someInstance = SomeClass()
someInstance.classPointer = SomeOtherClass.self
// Check if the instance's classPointer class conforms to the SomeProtocol protocol
if let conformingClass = someInstance.classPointer as? SomeProtocol.Type {
// If so, execute the class function in SomeProtocol on the instance's classPointer
conformingClass.someClassFunction()
}
And it works :).

Swift delegate does not inherit NSObject

I am trying to implement some sort of delegate broadcaster (Observer Pattern) in Swift to register multiple delegates. To use the "isEqual" function I need the generic to inherit from NSObject
To avoid duplicate code I prepared a generic DelegateBroadcaster:
import UIKit
class DelegateBroadcaster<T : NSObject>: NSObject {
var delegates : [T]
override init() {
delegates = []
}
func addDelegate(newDelegate : T) {
delegates.append(newDelegate)
}
func removeDelegate(oldDelegate : T) {
for i in 0...delegates.count-1 {
if (oldDelegate.isEqual(delegates[i])) {
delegates.removeAtIndex(i)
break
}
}
}
}
and subclass this for any specific broadcaster.
import UIKit
class NavigationControllerBroadcaster : DelegateBroadcaster<UINavigationControllerDelegate> {
}
But I get a strange error: "DelegateBroadcaster requires that 'UINavigationControllerDelegate' inherit from NSObject"
This is strange because the class reference by apple (Class Reference) says that UINavigationControllerDelegate inherits from NSObject.
So why do I get an error?
You are confusing class NSObject (NSObject class) and protocol NSObject (NSObject protocol, in Swift called NSObjectProtocol).
UINavigationControllerDelegate is a protocol and cannot inherit from class NSObject, it inherits from NSObjectProtocol (switch your documentation to Swift, you will see the difference).
UINavigationControllerDelegate is not a concrete type, it is a Protocol and therefore cannot be used as the type signature for the DelegateBroadcaster

How to declare a function with a concrete return type conforming to a protocol?

EDIT:
This question was written before swift added the some keyword, making it obsolete
In objective-c I could declare a method with a return type:
-(UIView<MyProtocol> *)someMethod;
In this example the method returns a UIView that conforms to a protocol MyProtocol.
I want to do something like that in swift:
protocol MyProtocol {
var someProperty : Int {get set}
}
protocol MyDelegate {
func someMethod() -> UIView : MyProtocol // the view should conform to the protocol - I don't care what kind of view it is - I don't want to define a specific type of view
}
In general - The delegate should return a UIView with the var "someProperty"
I don't want to define a concrete UIView class.
I want the user to be able to return any type of UIView (As long as it conforms to the protocol)
The syntax I wrote is invalid - How should I be writing it?
You could just use the protocol as type:
protocol MyDelegate {
func someMethod() -> MyProtocol
}
And use it like this:
protocol MyProtocol {
var someProperty : Int {get set}
}
class CustomView: UIView, MyProtocol {
var someProperty = 2
}
protocol MyDelegate {
func someMethod() -> MyProtocol
}
struct Delegate: MyDelegate {
func someMethod() -> MyProtocol {
return CustomView()
}
}
let delegate = Delegate()
let view = delegate.someMethod()
let property = view.someProperty // property = 2
This is not possible in Swift. Not everything possible in Obj-C has to be possible in Swift. When creating a type requirement you can only combine protocols using the protocol<..., ...> syntax but you can't combine a class and a protocol.
Technically, this should be good for your architecture. You can probably find a workaround but I would advice against it. There is a reason to avoid combining classes with protocols because the interfaces are much more difficult to handle. Most OOP languages don't have that syntax. Many commonly used languages don't even have a syntax to combine protocols.
protocol MyProtocol {
var someProperty : Int {get set}
}
protocol MyDelegate {
func someMethod<T: UIView & MyProtocol>() -> T // the view should conform to the protocol - I don't care what kind of view it is - I don't want to define a specific type of view
}
class MyDelegateTestView : UIView, MyProtocol {
var someProperty: Int = 10
}
class MyDelegateTestClass : MyDelegate {
func someMethod<T>() -> T where T : UIView, T : MyProtocol {
return MyDelegateTestView() as! T
}
}
The question was written before the days of swift-ui
The "some" keyword has solved it by allowing opaque types to be returned from functions
protocol MyDelegate {
func someMethod() -> some MyProtocol
}
Here below is a way.
func myMethod(string: String) -> MyClass:MyProtocol? {
}
You can use without optional type as MyClass: MyProtocol.

Resources