instance methods from class methods swift - ios

I have a class TestClass and a class & instance method inside it
class TestClass {
class func classMethod(){
print("how do i call instance method from here")
}
func instanceMethod(){
print("call this instance method")
}
}
My question is how do i call that instanceMethod from classMethod??
One way i have noticed is
class func classMethod(){
TestClass().instanceMethod()
}
But,Is this the good way to do?

What you are trying to do rarely makes any sense from a design perspective.
By definition, an instance method operates on an instance of an object.
For example, it might require access to some instance members, or somehow meddle with the state of the object you call the method on.
class methods on the other hand do not require an instance to be able to call them - and should in general only operate on the given parameters, not be dependant on shared state.
If you need to call instanceMethod() in classMethod(), and instanceMethod() does not require any state - why is it not also a class method, or a (global) pure function?

You can pass the instance object as a parameter to the class method, and then call the instance method of the object:
class TestClass {
class func classMethod(obj:TestClass){
print("how do i call instance method from here")
obj.instanceMethod()
}
func instanceMethod(){
print("call this instance method")
}
}

To call the instance method, you need an instance of TestClass. That's what TestClass() is getting you when you call TestClass().instanceMethod().
If you want to call it from a specific instance, you could pass it in as a parameter to the class function: class func classMethodUsingInstance(instance: TestClass)
If you don't need a specific instance for instanceMethod(), maybe consider making it a class method as well.

Related

How to Mock an object with protected init

I am trying to Mock an amazon services object to perform UnitTesting on a related code. I have done it as follows but each time the init is hit it crashes with error failed:
caught "NSInternalInconsistencyException", "- init is not a valid
initializer
Normally the same object will be created using there factory method, so it seems the initializer is made private or something. How can such object be mocked ?
class MyAWSiOTDataManager : AWSIoTDataManager {
override func publishString(_ string: String, onTopic topic: String, qoS qos: AWSIoTMQTTQoS) -> Bool {
print("publish string called")
return true
}
override init() {
}
}
let manager = MyAWSiOTDataManager()
You must call the designated initializer of AWSIoTDataManager inside your init call and remove the override decorator. That is why you got the error.
You can not mock something by subclassing it. With Swift, mocks are usually provided through a shared protocol. Define a protocol for the interface that you use from the third party library. Create an empty extension on the library with your protocol (there should be no code needed). Then implement a mock object against the protocol for use in your tests.

Is all overridable methods are lifecycle methods

My concern is the following,
If I create a Class with some method and inherit it then which methods are called lifecycle methods.
Are all overridable methods lifecycle methods? And in which category does it fall e.g OOPS ,OOAD
Example:- In iOS viewDidLoad is a lifecycle method but didReceiveMemoryWarning is not.
If it is not called a lifecycle method , is it called a overridable method?
Methods don't have type like life cycle method or overridable method etc.
UIViewController have it's own life cycle as per it's behavior that it is load or it appear etc.
And overriding is concept of inheritance. So there is no standard type like life cycle or overridable. Methods which are called from initialization of viewController to Disappearance, comes under lifecycle of viewcontroller.
We use override when we want to add some features to our method from super class.
If you create a class and implement UIViewcontroller as superclass.UIViewController has predefine method such as viewDidload, viewWillAppear,viewDidDisapear and others. If you want to add some features to superclass methods you should use override prefix. Override is used when you implement method of superclass and add your code.
For example
class Student{
func address(){
var add1 = "drn"
}
func phoneNumber(){
var no = 9806569690
}
}
//create another class and add student as superclass
class Classroom: Student{
//here address is method from superclass student so i am using override prefix
override func address(){
var add2 = "ktm"
}
}
Actuctually i am typing from mobile phone. So i could not give you good example.

Swift: Unable to override operationDidFinish from GroupOperation class

In a custom subclass of GroupOperation, I'm trying to override operationDidFinish(). When I attempt to implement the function in my subclass, I get this error message:
Method does not override any method from its superclass
If I remove the override keyword, I get
Method 'operationDidFinish(:withErrors:)' with Objective-C selector
'operationDidFinish:withErrors:' conflicts with method
'operationDidFinish(:withErrors:)' from superclass 'GroupOperation'
with the same Objective-C selector
Weirdness. I'm pretty sure my method signature is spot on, and I'm not trying to overload an obj-c method, so all should be well. What gives?
For reference, my class looks like this:
class ServerAuthenticationOperation: GroupOperation {
// properties... initializer stuff...
override func operationDidFinish(operation: NSOperation, withErrors errors: [NSError]) {
print("I finished!")
}
}
I assume you're using Swift 2.
Objective-C does not support method overloading, so you have to select a different name for your method. Or, you can try these options:
Rename the method using the #objc(newMethodName:)
Use #nonobjc
Edit:
It seems working for the repo you provided, you can check it here. https://www.dropbox.com/s/hb07u3hyjhjuews/OverrideTest.zip?dl=0

Swift class with only class methods and a delegate?

I want a class with all class methods. I would like to use a delegate so my view controllers (conforming to the protocol) can call AlertFactory.passwordResetSucess() and display the alert.
Is there a way to make this this work? A way to use the delegate from this class?
Is this bad practice? Bad form? Why?
What's a good way to make this happen? There will be other class methods used in several views.
Thanks!
protocol AlertFactoryDelegate
{
func showAlert(alert: UIAlertController)
}
class AlertFactory: NSObject {
let delegate: AlertFactoryDelegate!
class func passwordResetSuccess()
{
var alert = UIAlertController(title: "Success!", message: "Yay", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Continue", style: UIAlertActionStyle.Default, handler: nil))
delegate.showAlert(alert)
}
}
You can set delegate to be static, and access it with AlertFactory.delegate
class AlertFactory: NSObject {
static weak var delegate: AlertFactoryDelegate?
class func passwordResetSuccess() {
...
self.delegate?.showAlert(alert)
}
}
To create a delegate:
class SomeClass: AlertFactoryDelegate {
... // Implement everything the protocol requires
}
// Asssing a delegate
AlertFactory.delegate = SomeClass()
You cannot set an instance variable on a class without instantiating the class first. Is there a reason you don't want to instantiate the class, and just want to use class methods instead? If you feel that you have good reason to use class methods over instance methods, then you have two potential options:
Pass a delegate as a parameter to the class method.
Use Completion Blocks instead of Delegation. Here's a decent example in swift.
In my personal experience I find blocks to be preferable.
EDIT: I haven't used Swift that much lately, but as #Skrundz pointed out you can indeed use a static variable on a class in Swift.
You could use the SINGLETON command pattern, its a very common practice. You should read up on it, but basically means there is only 1 ever instance of it and you can call methods off of it when needed (or send things to it as needed). Common examples are EventSystem objects or GlobalObserver objects, Factories, and ContextManagers.
Here is information on it:
https://sourcemaking.com/design_patterns/singleton
Using a SINGLETON has tradeoffs, but can be very useful in many situations. This seems like a good pattern for your problem.
You need to initialize your delegate when your app starts. From then on, when another view controller needs to set that delegate you can assign it: (this assumes you made delegate public and its a SINGLETON)
_myViewController.actionThatRequiresDelegate = AlertFactory.delegate
As mentioned in one of the other answers, using Swifts trailing syntax closure system is a great way to use anonymous functions and you could do your logic in there, or communicate with your delegate in there.
update
Initialize in the AppDelegate.swift:
override init()
{
AlertFactory.init()
}
Then in your AlertFactory
public static AlertFactoryDelegate myDelegate
public static func init()
{
myDelegate = new AlertFactoryDelegate()
}

Doesn't work to call instance method from class method

I'm trying to call an instance method from a class method in Swift, but I keep getting the error "Missing argument for parameter #1 in call" on the "someMethod()" call.
Do you know why?
Here's the code:
class ViewController: UIViewController {
class func updateData() {
someMethod()
}
func someMethod() {
NSLog("someMethod")
}
}
updateData is declared as a class method (i.e. static), and it's executed in the context of the class type and not a class instance. On the other hand, someMethod is an instance method.
You cannot execute an instance method from a static method, unless you provide an instance.
Without knowing the logic of your app, it's hard to figure out how the problem should be solved. Some possible solutions:
make uploadData an instance method, by removing class from its signature:
func updateData() { ...
make someMethod a static method:
class func someMethod() { ...

Resources