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

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

Related

Cast AppDelegate in SwiftUI Lifecycle

How do you do the cast below, in an App with SwiftUI Lifecycle, where AppDelegate is implemented as NSApplicationDelegateAdaptor?
let appDelegate = NSApplication.shared.delegate as! AppDelegate
// or
let appDelegate = NSApp.delegate as! AppDelegate
The above throws the following error:
Could not cast value of type 'SwiftUI.AppDelegate' (0x1e28fae40) to 'MyApp.AppDelegate' (0x102d277c0).
Background is using AppDelegate in an Extension
extension NSStatusBarButton {
public override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
let appDelegate = NSApp.delegate as! AppDelegate
// do stuff with appDelegate on MouseDown Event
}
}
We must not cast, because NSApp's delegate is not our delegate, but internal, which redirects some callbacks to that one injected via adapter.
We can access our delegate directly via variable of adapter:
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
or via EnvironmentObject (for that AppDelegate have confirm to ObservableObject protocol), which is injected into ContentView for us automatically and so available inside all subviews:
struct MyView: View {
#EnvironmentObject var appDelegate: AppDelegate
// ...

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

SwiftUI: Access #EnvironmentObject from AppDelegate

I want to use the applicationWillTerminate function to save some user defaults before the app closes. The data I want to save is stored in an EnvironmentObject.
How can I access it from the AppDelegate class?
An #EnvironmentObject doesn't need to be instantiated directly in your SwiftUI objects; rather, it can be allocated somewhere else (for example, your UISceneDelegate) and then passed through using the .environment(…) function.
You could also allocate it on your AppDelegate, and pass that object though to your views in UISceneDelegate.scene(_:willConectTo:options:) method.
Paul Hudson has a good description of all of this at https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views
In case someone needs code example for this answer.
1.Create class that conforms to ObservableObject
class Test: ObservableObject{ }
2.in AppDelegate.Swift declare var myVar = Test()
class AppDelegate: UIResponder, UIApplicationDelegate {
var myVar = Test()
//****
}
3.in SceneDelegate.swift in "if let windowScene = scene as? UIWindowScene {" change the code like this :
if let windowScene = scene as? UIWindowScene {
let myVar = (UIApplication.shared.delegate as! AppDelegate).myVar
window.rootViewController = UIHostingController(rootView: contentView.environmentObject(myVar))
self.window = window
window.makeKeyAndVisible()
}

Passing an object to a ViewController from AppDelegate

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

How do I get a reference to the AppDelegate in Swift?

How do I get a reference to AppDelegate in Swift?
Ultimately, I want to use the reference to access the managed object context.
The other solution is correct in that it will get you a reference to the application's delegate, but this will not allow you to access any methods or variables added by your subclass of UIApplication, like your managed object context. To resolve this, simply downcast to "AppDelegate" or what ever your UIApplication subclass happens to be called. In Swift 3, 4 & 5, this is done as follows:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let aVariable = appDelegate.someVariable
Swift 4.2
In Swift, easy to access in your VC's
extension UIViewController {
var appDelegate: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}
Convenience Constructors
Add in AppDelegate Class at the end of code
Swift 5.7
func appDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
To use AppDelegate reference anywhere in code?
For example: Call AppDelegate Method named setRoot
appDelegate().setRoot()
This could be used for OS X
let appDelegate = NSApplication.sharedApplication().delegate as AppDelegate
var managedObjectContext = appDelegate.managedObjectContext?
It's pretty much the same as in Objective-C
let del = UIApplication.sharedApplication().delegate
Here is the Swift 5 version:
let delegate = UIApplication.shared.delegate as? AppDelegate
And to access the managed object context:
if let delegate = UIApplication.shared.delegate as? AppDelegate {
let moc = delegate.managedObjectContext
// your code here
}
or, using guard:
guard let delegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let moc = delegate.managedObjectContext
// your code here
Appart from what is told here, in my case I missed import UIKit:
import UIKit
SWIFT < 3
Create a method in AppDelegate Class for ex
func sharedInstance() -> AppDelegate{
return UIApplication.sharedApplication().delegate as! AppDelegate
}
and call it some where else for ex
let appDelegate : AppDelegate = AppDelegate().sharedInstance()
SWIFT >= 3.0
func sharedInstance() -> AppDelegate{
return UIApplication.shared.delegate as! AppDelegate
}
Try simply this:
Swift 4
// Call the method
(UIApplication.shared.delegate as? AppDelegate)?.whateverWillOccur()
where in your AppDelegate:
// MARK: - Whatever
func whateverWillOccur() {
// Your code here.
}
Here's an extension for UIApplicationDelegate that avoids hardcoding the AppDelegate class name:
extension UIApplicationDelegate {
static var shared: Self {
return UIApplication.shared.delegate! as! Self
}
}
// use like this:
let appDelegate = MyAppDelegate.shared // will be of type MyAppDelegate
Make sure you import UIKit
let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate
it is very simple
App delegate instance
let app = UIApplication.shared.delegate as! AppDelegate
you can call a method with one line syntax
app.callingMethod()
you can access a variable with this code
app.yourVariable = "Assigning a value"
extension AppDelegate {
// MARK: - App Delegate Ref
class func delegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}
In my case, I was missing import UIKit on top of my NSManagedObject subclass.
After importing it, I could remove that error as UIApplication is the part of UIKit
Hope it helps others !!!
I use this in Swift 2.3.
1.in AppDelegate class
static let sharedInstance: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
2.Call AppDelegate with
let appDelegate = AppDelegate.sharedInstance
In Swift 3.0 you can get the appdelegate reference by
let appDelegate = UIApplication.shared.delegate as! AppDelegate
As of iOS 12.2 and Swift 5.0, AppDelegate is not a recognized symbol. UIApplicationDelegate is. Any answers referring to AppDelegate are therefore no longer correct. The following answer is correct and avoids force-unwrapping, which some developers consider a code smell:
import UIKit
extension UIViewController {
var appDelegate: UIApplicationDelegate {
guard let appDelegate = UIApplication.shared.delegate else {
fatalError("Could not determine appDelegate.")
}
return appDelegate
}
}
In the Xcode 6.2, this also works
let appDelegate = UIApplication.sharedApplication().delegate! as AppDelegate
let aVariable = appDelegate.someVariable