I have a struct defined in my ViewController as follows:
struct Meme {
var topText : String
var bottomText : String
var originalImage : UIImage
var memedImage: UIImage
}
Now when I try to access the struct from appDelegate using the following code, I get an unresolved identifier error:
var memes = [Meme]()
can someone please explain why this is happening and how can i access the viewController struct from my appDelegate?
Thanks!
You can't access the properties of a class without having an instance of it.
In AppDeletegate file do this:
// create instance of your viewcontroller class
let viewController = ViewController()
// access the property
viewController.memes = [Meme]()
This is possible in another way to:
import UIKit
var memes = [Meme]()
class ViewController: UIViewController {
}
ok the memes are not exacly in the scope of UIViewController, but they are in the same file, like this they are global variable.
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(memes[0].bottomText)
return true
}
Wish you all the best.
Assuming the struct is defined inside your ViewController class like you said, you will need to access it using the namespace of the ViewController in the following way:
var memes = [MyViewController.Meme]()
I actually figured this out long back. Sorry for the delay in update. People with the same problem, please create a new swift file called "Meme.swift" and then write the meme struct inside that file. Your problem should be solved now. Thanks!
Related
I have tried many different resources online but they all seem to use app delegate files and I get TOTALLY confused.
All I want to be able to do is read and write from the cloud firestore to my swift app
I have installed firebase and the firestore via the package manager and it can't seem to find the Firestore Manager
import SwiftUI
import Firebase
#main
struct RecipyApp: App{
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#StateObject var firestoreManager = FirestoreManager()
var body: some Scene{
let viewModel = AppViewModel()
WindowGroup{
ContentView()
.environmentObject(viewModel)
.environmentObject(firestoreManager)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}
MY CODE.
What can I do to fix my problem?
Many thanks
Solution 1:
Delete The Excess Package And Run The App
Solution 2:
Go To Xcode Preference > Location, Delete Derived Data
I went through the steps to set up Firebase on my app and it tested well. But when I created a custom swift class to make functions to manage the database, it crashes and says "failed to get default firdatabase instance. must call firapp.configure() before using firdatabase". I called configure() in the AppDelegate but it doesn't seem to be passing through to my custom class. Below is the error I get, my part of the AppDelegate where i called FirebaseApp.configure(), and the custom class. Thanks in advance.
DatabaseTestApp[7814:336288] *** Terminating app due to uncaught exception 'FIRAppNotConfigured', reason: 'Failed to get default FIRDatabase instance. Must call FIRApp.configure() before using FIRDatabase.'
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
}
my custom class:
import Foundation
import UIKit
import FirebaseDatabase
class FirebaseClass
{
var ref:DatabaseReference?
init ()
{
ref = Database.database().reference()
}
}
Assuming you are creating some sort of class called FirebaseManager, do the following:
class FirebaseManager {
public static let instance = FirebaseManager()
private init(){
FirebaseApp.configure()
}
}
The way I currently load my data is in the viewWillAppear on their specific view controllers. My question is should I load all the data on the Home/Main View Controller and pass the data that way? Or is the current way Im doing it better?
I know this is subjective, I'm loading ALOT of data.
Structure:
If you do not want the data to persist between app processes (when the app is closed the data is cleared), you can use Global Variables. When it comes to retrieving data, I suggest you to create a function in AppDelegate called retrieveFromFirebase(), containing every piece of code needed to retrieve data in your app, for all the UIViewControllers of your app. Then you should call it inside
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {}
Then, inside your function, you should assign the snapshot's value to the global variable declared earlier.
Example:
This is an example of how to setup AppDelegate.swift for this:
import UIKit
import CoreData
import Firebase
//declaration of the global variable
var username = String()
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
retrieveFromFirebase()
return true
}
func retrieveFromFirebase(){
// get the data from Firebase
let ref = FIRDatabase.database().reference()
ref.child("username").observe(FIRDataEventType.value, with: { snapshot in
username = snapshot.value! as! String
})
}
// other methods from AppDelegate.swift
}
And when you get to the desired ViewController, set your viewDidAppear function to this:
override func viewDidAppear(_ animated: Bool){
super.viewDidAppear(animated)
yourLabel.text = username
}
And you can just use your username anywhere in the current Module.
Hope it helps!
there are some codes i am writting.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, XPageViewControllerDataSource {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let pageVeiwController = XPageviewcontroller()
pageVeiwController.dataSource = self
self.window?.rootViewController = UINavigationController(rootViewController: pageVeiwController)
self.window?.makeKeyAndVisible()
return true
}
func XPageNumberOfControllers() -> NSInteger {
return 5
}
func XPageControllersTitle(index: NSInteger) -> String {
return "ViewController"+"title"+String(index)
}
func XPageWillShowController(index: NSInteger) -> UIViewController {
let vc = ViewController()
return vc
}
}
i am writing a pure coding programme without mainstoryboard in Xcode,
this is my appdelegate.swift, i try to implement the protocol from my XPageViewController.swift, there are 3 functions in protocol which I have already written in appdelegate. And i have also declared in XPageViewController.swift
var dataSource:XPageViewControllerDataSource!
{
didSet{
self.numberOfControllers = self.dataSource.XPageNumberOfController()
self.addViewToSelf()
}
which is using in appdelegate
pageVeiwController.dataSource = self
but still a error occur there,
shows"Type 'AppDelegate' does not conform to protocol 'XPageViewControllerDataSource'"
i almost run out solutions :D
do anyone have any ideas can help me to solve this?
Can you show us what the XPageViewControllerDataSource protocol comprises of?
Command+Click it in Xcode to view the actual protocol.
Either way, when you view the protocol it should show you what the requirements for the protocol are.
Trying to set up XCGLogger and receiving error:
Ambiguous reference to member 'log'
I see this issue was already raised but I'm not clear on the solution..
Per the install guide added this global constant to AppDelegate.swift:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let log = XCGLogger.defaultInstance()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
log.setup(.Debug, showThreadName: true, showLogLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: nil, fileLogLevel: .Debug)
return true
}
Then in individual source files:
import XCGLogger
log.debug("A debug message")
What is the proper usage?
The issue is rather simple. If you declare log inside AppDelegate, you are making an instance variable. To access it, you will have to access it as instance variable:
(UIApplication.sharedApplication().delegate as! AppDelegate).log.debug("test")
If you want log to be accessible everywhere, you will have to make it a global constant:
In your AppDelegate, declare a global constant to the default XCGLogger instance.
let log = XCGLogger.defaultInstance()
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
(there is no need to declare it in AppDelegate file, you can basically put it anywhere in your code)
or make it static:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static let log = XCGLogger()
and access it using:
AppDelegate.log.debug(...)
To explain the ambigious reference, there is a mathematical function called log, and there is also a log function in the malloc.h file. Since you are passing a String as the first parameter and neither of the two functions is a match, the compiler warns you that it does not know which of the two functions you want to use.
Also I guess it's better to create global constant file and create something like this (if you've declared log in AppDelegate):
let LOG = (UIApplication.sharedApplication().delegate as! AppDelegate).log
and then simple use LOG.error("error")