initWithDelegate for Objective-C class - ios

I have import this Objective-C class in a swift project.
MMLANSCanner.h
#import <Foundation/Foundation.h>
#class Device;
#protocol MMLANScannerDelegate;
#protocol MMLANScannerDelegate <NSObject>
#required
- (void)lanScanDidFinishScanningWithStatus:(MMLanScannerStatus)status;
- (void)lanScanDidFailedToScan;
#optional
- (void)lanScanProgressPinged:(float)pingedHosts from:(NSInteger)overallHosts;
#end
#pragma mark - Public methods
#interface MMLANScanner : NSObject
-(instancetype)initWithDelegate:(id <MMLANScannerDelegate>)delegate;
#property(nonatomic,weak) id<MMLANScannerDelegate> delegate;
#property(nonatomic,assign,readonly)BOOL isScanning;
- (void)start;
- (void)stop;
#end
I successfully created the bridging header and make the MainVC.Swift to conform to MMLANScannerDelegate.
Then I tried to initialise the MMLanScanner with delegate self.
import UIKit
import Foundation
class MainVC: UIViewController, MMLANScannerDelegate {
var presenter = MMLANScanner(delegate:self)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func lanScanDidFindNewDevice(_ device: Device!) {
}
func lanScanDidFailedToScan() {
}
func lanScanDidFinishScanning(with status: MMLanScannerStatus) {
}
func lanScanProgressPinged(_ pingedHosts: Float, from overallHosts: Int) {
}
}
But I get error:
Argument passed to call that takes no arguments
Any ideas how to implement initWithDelegate function that I had in Objective-C?

MLANScanner doesn't take a delegate argument to its init method (delegate is a property of MLANScanner).
You also have a problem with the definition of your presenter property since self isn't valid at the time MainVC is created.
Do this instead:
let presenter = MLANScanner()
override func viewDidLoad() {
super.viewDidLoad()
presenter.delegate = self
}
based on edit to question:
var presenter: MLANScanner!
override func viewDidLoad() {
super.viewDidLoad()
presenter = MLANScanner(delegate: self)
}
Note: My edited answer assumes there is a Swift bridge somewhere that exposes an init(delegate:) method. There may not be and making one is beyond the scope of this question. Since the delegate is not private or read-only you can almost certainly use the first version I posted.

Related

How to automatically generate methods like ViewDidLoad

I want to create a custom class that extends uiviewcontroller with a function that when I create a subClass of my custom class, that function generate automatically. like viewDidLoad and didReceiveMemoryWarning in subclasses of UIViewController.
what can I do?
My CustomViewController :
class CustomViewController: UIViewController
My subclass of CustomViewController :
class MySubClass: CustomViewController {
override func generatedFunction() {
//Do something
}
}
Use code snippets.
Go to /Applications/Xcode/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates and edit the templates.
You can create a CustomViewController and then add your method to it and then call the method in the viewDidLoad. Like this
import UIKit
class CustomViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.generatedFunction()
}
public func generatedFunction() {
//Do something
}
}
Then you can use it like this,
import UIKit
class ViewController: CustomViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func generatedFunction() {
super.generatedFunction()
// Do Something
}
}
You need to make sure that if you override viewDidLoad, then you need to call super.viewDidLoad() in it.

Swift can't call protocol method via delegate

I have two classes. One class is named ViewController and the other class is named TabView.
My goal is to call a function changeTab() which is inside the TabView class from the ViewController.
Somehow I am having trouble with it because everytime my delegate is nil.
Here is my code for ViewController:
protocol TabViewProtocol: class {
func changeTab()
}
class ViewController: NSViewController {
// delegate
weak var delegateCustom : TabViewProtocol?
override func viewDidLoad() {
print(delegateCustom) // outputs "nil"
}
buttonClickFunction() {
print(delegateCustom) // outputs "nil"
delegateCustom?.changeTab() // doesn't work
}
}
Here is my code for TabView:
class TabView: NSTabViewController, TabViewProtocol {
let myVC = ViewController()
override func viewDidLoad() {
super.viewDidLoad()
myVC.delegateCustom = self
}
func changeTab() {
print("test succeed")
}
}
Can someone explain me what I am doing wrong? - I am new to delegates and protocols...
You are using the delegate pattern wrongly. It is hard to tell which controller you want to define the protocol for and which one you want to adopt it - but here is one possible way.
// 1. Define your protocol in the same class file as delegate property.
protocol TabViewProtocol: class {
func changeTab()
}
// 2. Define your delegate property
class ViewController: NSViewController {
// delegate
weak var delegateCustom : TabViewProtocol?
override func viewDidLoad() {
// It should be nil as you have not set the delegate yet.
print(delegateCustom) // outputs "nil"
}
func buttonClickFunction() {
print(delegateCustom) // outputs "nil"
delegateCustom?.changeTab() // doesn't work
}
}
// 3. In the class that will use the protocol add it to the class definition statement
class TabView: NSTabViewController, TabViewProtocol {
let myVC = ViewController()
override func viewDidLoad() {
super.viewDidLoad()
myVC.delegateCustom = self
// Should output a value now
print(myVC.delegateCustom) // outputs "self"
}
func changeTab() {
print("test succeed")
}
}
you are creating a new instance in this line:
let myVC = ViewController()
you should get existing instance of your ViewController.then set
myVC.delegateCustom = self

Looking understand why delegate keep alive

I have the following structure
Main ViewController: it is responsible to call the (A) view controller.
(A) ViewController: create an CustomClass instance and has a delegate for this class.
CustomClass: in each period of 1 second, a message is sent to (A) view controller via delegate.
Until here all works fine. Once I returned to Main ViewController the delegate keep alive, in other words, the delegate updates A(ViewController) variable. I checked that viewDidDisappear of (A) ViewController is called.
When I return again from Main ViewController to (A) ViewController, a new variable instance is created. I don't understand this anyway.
Besides this doubt, I would like to understand why the delegate keep alive when I return to main view controller. I am using a UINavigationItem to navigation.
I am a beginner in IOS development.
Thanks advanced!!!
Edit 1:
The (A)ViewController is called from MainViewController by Segue. The segue was added via storyboard.
MainViewController.swift
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
AViewController.swift
class ScanDevices : UIViewController, CustomClassDelegate {
var myInts : [Int] = []
var customClass : CustomClass!
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad")
if customClass == nil {
customClass = CustomClass()
customClass.customClassDelegate = self
}
}
override func viewWillAppear(animated: Bool) {
print("viewWillAppear")
}
override func viewDidAppear(animated: Bool) {
print("viewDidAppear")
}
override func viewWillDisappear(animated: Bool) {
print("viewWillDisappear")
}
override func viewDidDisappear(animated: Bool) {
print("viewDidDisappear")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func didDiscoverPeripheralInt(peripheral: Int) {
myInts.append(peripheral)
print("Number = \(myInts.count)")
}
}
CustomClass.swift
class CustomClass : NSObject {
var customClassDelegate : CustomClassDelegate?
// MARK: init
override init() {
super.init()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "writeInt", userInfo: nil, repeats: true)
}
func writeInt () {
CustomClassDelegate?.didDiscoverPeripheralInt(3)
}
}
var customClassDelegate : CustomClassDelegate?
You are holding a string reference to your delegate.
It needs to be
weak var customClassDelegate : CustomClassDelegate?
Take a look at the following document :
http://krakendev.io/blog/weak-and-unowned-references-in-swift
Your CustomClass holds strong reference to the delegate. You have to mark the property with weak:
weak var customClassDelegate : CustomClassDelegate?

assigned delegate, but function is not called

Hi guys i would want to fire a method in SecondViewController from FirstViewController when the condition is meet. So i have used delegate to do so and my code is as follow:
FirstViewController:
import UIKit
import CoreBluetooth
import Foundation
class BluetoothViewController: UIViewController, ValueChangedDelegate {
if (characteristic.UUID == CBUUID(string: "2AF0")){
DataReceived.Single_Axis = Double(CharValue)
func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {
let singleaxisview = SingeAxisViewController()
singleaxisview.delegate = self
singleaxisview.valueChangedNotifyEveryone()
println("btfired")
}
SecondViewController
import UIKit
import CoreGraphics
protocol ValueChangedDelegate
{
func valueChanged(nValue : String)
}
class SingeAxisViewController: UIViewController {
var delegate : ValueChangedDelegate?
func valueChangedNotifyEveryone()
{
println("hello")
delegate?.valueChanged("changed value")
}
Can somebody point out to me what i missed?
Instead of BTController!.delegate = self you will have to use object of FirstViewController and set the delegate and you will also need to initialise the FirstViewController object. here is a sample code if you want to implement it. the first view controller implements the delegate methods and on call of btnClicked the second view controller is called and you get the response back to first view controller in the valueChanged method
import UIKit
class FirstViewController: UIViewController, ValueChangedDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
lbl.text = "inital value"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
#IBOutlet weak var lbl: UILabel!
#IBAction func btnClicked(sender: AnyObject)
{
let secondViewController = SecondViewController()
secondViewController.delegate = self
secondViewController.valueChangedNotifyEveryone()
}
func valueChanged(nValue : String)
{
print(nValue)
lbl.text = nValue
}
}
Second view controller which implements the protocol and the also calls the protocol method from valueChangedNotifyEveryone method
import UIKit
protocol ValueChangedDelegate
{
func valueChanged(nValue : String)
}
class SecondViewController: UIViewController {
var delegate : ValueChangedDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func valueChangedNotifyEveryone()
{
delegate?.valueChanged("changed value")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

Swift error declaring delegate

I'm new in swift and I'm studying the delegate and protocols. In my test application I'm using this protocol declaration (in ViewController1) and I have this code:
import UIKit
//Protocol declaration
protocol viewController1Delegate
{
func didFinish(controller:ViewController1,text:String)
}
//ViewController1 class
class ViewController1: UIViewController {
//delegate declaration for viewController1
var delegate:ViewController1? = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
valore.text=valoreInput
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func doneWithOK(sender: AnyObject) {
delegate?.didFinish(self,"done")
}
}
My problem is XCode show me an error: ViewController1 does not have a member named didFinisch. What is wrong in my code? Someone can help me to understand the problem?
delegate should be viewController1Delegate? and not ViewController1?.

Resources