Passing an object to a ViewController from AppDelegate - swift

In my application, a Connection object is initialized in my AppDelegate.swift, applicationDidBecomeActive().
How do I pass that Connection object to my ViewController subclass?

In AppDelegate create a property
private weak var viewController : ViewController?
In the view controller in viewDidLoad assign self to that property
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.viewController = self
Now you can access the view controller from AppDelegate

Instances like Connection are usually required throughout the application so the better idea is to create a shared instance of the required object and use anywhere we need.
class Connection{
static let sharedConnection = Connection()
....
}
usage:
let connection = Connection.sharedConnection

Related

In swift , how to implement a variable in the app delegate, in order to retrieve it everywhere in the app?

In swift, how to create a variable in the app delegate in order to retrieve it everywhere in the app?
I am not talking about NSManagedObject
I know that it begin with :
let appDelegate = UIApplication.shared.delegate as! AppDelegate
I have a class Personne
class Personne {
var One: String
var Two: Float
}
and another classe to create a Singleton:
class PersonneController {
var shared = Personne()
and in my app, i have created an instance like this:
var personne = Personne()
so every variable is retrieving by
personne.shared.myvariable
How to put personne in the app delegate, in order to retrieve it from everywhere?
1 . Create the instance of your "Personne" Class in AppDelegate
( var persnee = Personne())
2 . create a function in your AppDelegate to which will return instance of AppDelegate
class func appDelegate() -> AppDelegate
{
return UIApplication.shared.delegate as! AppDelegate
}
3 . You can call like this
AppDelegate.appDelegate(). persnee
Inside the class
class AppDelegate..... {
var name:String?
}
Then
let appDelegate = UIApplication.shared.delegate as! AppDelegate
print(appDelegate.name)
But for this it's better to make a singleton class like
class Service {
static let shared = Service()
var name:String?
}
Then
print(Service.shared.name)
or even make it a global variable
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let aVariable = appDelegate.blabla

How to access a referencing outlet from a different view controller?

I am new to Swift and Xcode. I am building an Financial Expense ios app.
In my first view controller, I created a referencing outlet for a label called expenseNum.
In my second view controller, I have a function for a button called Add Expense. When it is clicked, I need it to update the expenseNum variable with the amount of the expense.
What is the best way to go about this? I had created an object of the first view controller class and accessed it like "firstviewcontroller.expenseNum" but this will create a new instance of the class and I need it to be all the same instance so it can continuously add to the same variable. Thanks for the help!
You need a delegate
protocol SendManager {
func send(str:String)
}
In first
class FirstVc:UIViewcontroller , SendManager {
func send(str:string) {
self.expenseNum.text = str
}
}
when you present SecondVc
let sec = SecondVc()
sec.delegate = self
// present
In second
class SecondVc:UIViewcontroller {
var delegate:SendManager?
#IBAction func btnClicked(_ sender:UIButton) {
delegate?.send(str:"value")
}
}
// setting delegate
in viewDidLoad of SecondVc
if let first = self.tabBarController.viewControllers[0] as? FirstVc {
self.delegate = first
}
There are several ways you can pass data from ViewController2 to another ViewController1
The best way here is Protocol Delegates
Please follow below steps to pass data
In Your SecondViewController from where you want to send data back declare a protocol at the top of class declaration
protocol SendDataBack: class {
func sendDataFromSecondVCtoFirstVC(myValue: String)
}
Now in the class , declare a object of your protocol in same ViewController
weak var myDelegateObj: SendDataBack?
And now in your Add Expense button action just call the delegate method
myDelegateObj?.sendDataFromSecondVCtoFirstVC(myValue: yourValue)
Now go to your first ViewController
the place from where you have pushed/present to SecondViewController you must have taken the object of SecondVC to push to push from first
if let secondVC = (UIStoryboard.init(name: "Main", bundle: nil)).instantiateViewController(withIdentifier: "secondVCID") as? SecondViewController {
vc?.myDelegateObj = self
self.navigationController?.pushViewController(secondVC, animated: true)
**OR**
self.present(secondVC, animated: true, completion: nil)
}
now in your FirstViewController make an extension of FirstViewVC
extension FirstViewController: SendDataBack {
func sendDataFromSecondVCtoFirstVC(myValue: String) {
}
}
I think you can make a variable in your properties in second ViewController (before viewDidLoad method)
var delegate: FirstViewController? = nil
and use from the properties of the first view controller anywhere of the second view controller.
delegate!.mainTableView.alpha=1.0
//for example access to a tableView in first view controller
The simplest way to achieve this is to use a public var. Add a new Swift file to your project, call it Globals. Declare the public variable in Globals.swift like so:
public var theValue: Int = 0
Set its required value in the first ViewController, and you'll find you can read it in the second with ease.

CoreBluetooth set central delegate to another view controller

I have just started translating my app to Swift, I want the CBCentralManager.delegate to be set to another view controller(One that navigation controller pushes onto).
I am trying to do the same with following code:
let viewCont = self.storyboard!.instantiateViewControllerWithIdentifier("mainView")
self.navigationController?.pushViewController(viewCont, animated: true)
manager.delegate = viewCont
The variable manager is an instance of CBCentralManager and setting delegate to viewCont raises following error:
"Cannot assign value of type 'UIViewController' to type 'CBCentralManagerDelegate?'"
The declaration for the view Controller:
class MainViewController: UIViewController, CBCentralManagerDelegate
How can I solve the same?
You need to downcast the view controller you receive from instantiateViewControllerWithIdentifier. Without the downcast, all the compiler knows is that you have a UIViewController
let viewCont = self.storyboard!.instantiateViewControllerWithIdentifier("mainView") as! MainViewController
self.navigationController?.pushViewController(viewCont, animated: true)
manager.delegate = viewCont
Once you have the downcast using as! then the compiler knows that it has a MainViewController and since this class is also a CBCentralManagerDelegate it is happy.

How to pass value from navigationController to TabBarController

I have a Login project. The first view controller is NavController and I need to pass user data to tabBarController where I have 3 NavigationControllers.
I tried this.
let openNewVC = self.storyboard?.instantiateViewControllerWithIdentifier("mainNavID") as! UITabBarController
//openNewVC.token = token!
self.navigationController?.pushViewController(openNewVC, animated: true)
You can pass the data from your first view Controller to view controllers which are embedded like as below in UITabbarController.
UITabBarController -> UINavigationController -> UIViewController
You need to traverse the viewControllers instance of UITabBarController and UINavigationController in order to get the instance of UIViewController. Once you will get the instance of 'UIViewController' which is embedded into UITabbarController, you can assign the data as required.
For Example
if let tabBarController = self.storyboard?.instantiateViewControllerWithIdentifier("mainNavID") as? UITabBarController {
// Now you need to get View Controllers array from tabBarControllers which is UINavigationControllers
if let navigationControllers = tabBarController.viewControllers as? [UINavigationController] {
for navigationController in navigationControllers {
//Now you need to get the viewControllers from navigationController stack,
let viewControllers = navigationController.viewControllers
//Now you can assing desired value in viewControllers, I am assuming you need to assign the same value in all viewControler
for viewController in viewControllers {
}
}
}
}
The best way to pass the data in this kind of architecture using Singleton, Assume you created a class Session which member variable token.
class Session {
//Singleton
static let sharedInstance = Session()
//Token which you assign and you can use through out application
var token : String? = nil
}
Now, you can assign the token while pushing the UITabbarController.
let openNewVC = self.storyboard?.instantiateViewControllerWithIdentifier("mainNavID") as! UITabBarController
Session.sharedInstance.token = token
//openNewVC.token = token!
self.navigationController?.pushViewController(openNewVC, animated: true)
Same token you can use within UIViewController
override func viewDidLoad() {
super.viewDidLoad()
if let token = Session.sharedInstance.token {
//Now you have assigned token
}
}
You could try to set the values to the openNewVC as you would set a normal property.
Example:
//set instance
var openNewVC = self.storyboard?.instantiateViewControllerWithIdentifier("mainNavID") as! UITabBarController
// set properties
openNewVC.myFancyString = "Hello world!"
// set view controller active
self.navigationController?.pushViewController(openNewVC, animated: true)

Swift: How to access in AppDelegate variable from the View controller?

I would like to write in the text or csv (prefer) file the variable from the view controller.
Indeed I am doing a drawing app and I would like to write in the file the current position of the finger.
class ViewController: UIViewController {var lastPoint = CGPoint.zeroPoint ... }
I would like to have access to lastPoint.x and lastPoint.y from the AppDelegate. how I could do that ? Thank you.
Your question is full of confusion but if that's what you are looking for:
You can access the appDelegate by getting a reference to it like that:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
after that if you have store a property called lastPoint in your appDelegate you can access its components very simply like that:
let x = appDelegate.lastPoint.x
let y = appDelegate.lastPoint.y
If you need to access your viewController properties from the AppDelegate, then I suggest having a reference to your view controller in your appdelegate:
var myViewController: ViewController!
then when your view controller is created you can store a reference to it in the appdelegate property:
If your create your view controller outside of your appDelegate:
Swift 1-2 syntax
var theViewController = ViewController()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.myViewController = theViewController
Swift 3-4 syntax
var theViewController = ViewController()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myViewController = theViewController
If you create your view controller inside of your appDelegate:
self.myViewController = ViewController()
After that you can access your data from your viewcontroller from your appdelegate just by accessing its property like that:
let x = self.myViewController.lastPoint.x
let y = self.myViewController.lastPoint.y
Swift 3 Update
var theViewController = ViewController()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myViewController = theViewController
You can create a BaseViewController and write this
class BaseViewController {
lazy var appDelegate : AppDelegate {
return UIApplication.shared.delegate as? AppDelegate
}
}
and inherit other viewcontrollers with BaseViewController and access this by
class ViewController : BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(self.appDelegate?.lastPoint.x)
print(self.appDelegate?.lastPoint.x)
}}
I did manage to access my ViewController from the App delegate by creating an instance of ViewController in AppDelegate.swift, like:
var mainViewController = ViewController()
func applicationWillEnterForeground(_ application: UIApplication) {
mainViewController.myVariable = "Hello".
}
Still, I don't understand how does the AppDelegate "know" that mainViewController is supposed to point to that particular ViewController. As my application has a single view and a single ViewController, that's fine, but what it I had multiple ViewControllers associated with different UIViews? Appreciate if anyone here can shed a light into that.
Best Regards,
Andre