I'm calling this function in a swift file but it doesn't seem to work. For example, the timer isn't stopping when it's supposed to. Any ideas on how to fix it from the code shown below? Thanks.
var vc = ViewController()
func application(application: UIApplication, didFinishLaunchingWithOptions: [NSObject: AnyObject]?) -> Bool
{
vc.endGame()
vc.startButton!.hidden = false
vc.timer!.invalidate()
vc.timer = nil
// This is calling the function from the view controller
return true
}
Related
This question already has answers here:
loading url from scheme not processing first time - appdelegate vs viewcontroller
(2 answers)
Closed 3 years ago.
I would like to know how to call a function from another function within AppDelegate. It would be better to call this function from ViewController but could not get it to work.
I have in my AppDelegate.m the following code:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let geturl = url.host?.removingPercentEncoding;
UserDefaults.standard.set(geturl, forKey: "DeepLinkUrl")
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//I WANT CALL the upper function to set the URL IN HERE
return true
}
Since I don't know how to call the open url function from the ViewController.m I did this calling didFinishLaunchingWithOptions func from AppDelegate.m
My ViewController.m looks like:
#objc func appWillEnterForeground() {
print("app on foreground")
let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
appDelegate?.application(UIApplication.shared, didFinishLaunchingWithOptions: nil)
//ACTUALLY I WANT TO CALL THE SET URL FUNCTION IN STEAD OF didFinishLaunchingWithOption BUT DON'T KNOW HOW. SO I FOUND THIS WHICH IS BEING CALLED
let user = UserDefaults.standard
if user.url(forKey: "DeepLinkUrl") != nil{
let str = user.value(forKey: "DeepLinkUrl") as! String
print(str)
}
}
Any ideas?
You don't call this method at all. It is called by the operating system when your application is launched. You are absolutely not supposed to ever call it yourself.
Same with the other method, which will be called by the operating system when your application is asked to open a URL. Which might be the URL of a file, or a URL with a scheme that you registered for.
Set a breakpoint on appDidFinishLaunching, then on your viewDidLoad method, start debugging to get some idea what is going on. You might also consider reading Apple's documentation.
I am a self-taught newcomer to iOS programming and have worked through one beginner textbook. I'm trying to publish my first mobile application so I am going back through and cleaning up my code. The textbook I used stressed 'Dependency Injection' but I've struggled adapting their simple example to a more complex application.
The app operates as a shell and retrieves/parses txt files to populate. I successfully connected my model, which retrieves/parses the data, and the TableViewController that needs populated using the following code:
MyTableViewController {
var data: Data!
}
AppDelegate {
var window: UIWindow?
let data = Data()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let navCon = window!.rootViewController as! MyNavigationController
let tableVC = navCon.topViewController as! MyTableViewController
tableVC.data = data
return true
}
I then embedded that NavigationController within a TabBarController because the app will have other tabs. I tried the same process of setting the rootViewController and then drilling down until I could set my data variable, but I can't find the correct way to layer the ViewControllers and keep getting the error;
'fatal error: unexpectedly found nil while unwrapping an Optional value'
I tried two different approaches:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let tabBarCon = window!.rootViewController as! MyTabBarController
let navCon = tabBarCon.presentedViewController as! MyNavigationController
let tableVC = navCon.topViewController as! MyTableViewController
tableVC.data = data
return true
}
and
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let tabBarCon = window!.rootViewController as! MyTabBarController
let navCon = MyNavigationController()
tabBarCon.viewControllers = [navCon]
let tableVC = navCon.topViewController as! MyTableViewController
tableVC.data = data
return true
}
Is there a solution to correct this error or am I going about this process wrong? Again, I have a file that pulls in a txt file and then creates a dictionary. I need a separate TableViewController to be able to access that dictionary to populate itself, but I want to achieve this in the most efficient and apple promoted manner, not all in the same file as I did in my first design.
Thanks for the help!
For Dependency Injection I do recommend you use Typhoon. From mine experience it's one of the best tool. This will help you to achive app asembly like:
/*
* This is the definition for our AppDelegate. Typhoon will inject the specified properties
* at application startup.
*/
public dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
(definition) in
definition.injectProperty("cityDao", with: self.coreComponents.cityDao())
definition.injectProperty("rootViewController", with: self.rootViewController())
}
}
I found the solution through this thread;
Aassigning a value to a view controller from AppDelegate.swift
The result can be achieved by reconfiguring the second solution I attempted;
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let tabBarCon = window!.rootViewController as! MyTabBarController
let tabBarRootVCs: Array = tabBarCon.viewControllers!
let navCon = tabBarRootVCs[0] as! MyNavigationController
let tableVC = navCon.topViewController as! MyTableViewController
tableVC.data = data
return true
}
I want call a API when app is launched first time, in AppDelegate class didFinishLaunchingWithOptions and start all the execution after the response.
I guess you want to do a network call (e.g. to check for application version), wait for a response and then based on the response, start the application from the right view.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let startupVC = // Create a temporary view controller in Storyboard or XIB (can be the same as your launch view controller)
self.window.rootViewController = starupVC
self.window.makeKeyAndVisible()
networkCallWithReponseBlock {
let startingViewController = // your view controller from Storyboard, XIB or code
self.window.rootViewController = startingViewController
}
return true
}
I have scenario where my app receives an application:openURL:sourceApplication call from an extension and I want to open a tab in my tabBar and once its fully loaded then sendNext to a signal that the tabBar will be listening to once its loaded.
so sequence of events would be something like:
AppDelegate receives an OpenURL call
AppDelegate requests tabBar to load/open a tab called RemindersViewController
RemindersViewController RACSubject called RemindersLoadedSignal which i send to it a next value of true once the view has complete loading and binding
AppDelegate listens to the RemindersLoadedSignal and when it receives next from it it will emit its next signal to openURLSubject.
RemindersViewController listening to openURLSubject will perform some action since now its loaded and the signal was emitted.
class AppDelegate: UIResponder, UIApplicationDelegate {
let openURLSubject = RACSubject()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
RemindersLoadedSignal.subscribeNextAs({ (loaded:NSBool) -> () in
println("This subscription works for some reason")
})
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
myTabBar.selectTabWithClass(RemindersViewController.self)
//SendNext to openURLSubject once the tab is loaded
RemindersLoadedSignal.subscribeNextAs({ (loaded:NSBool) -> () in
println("This subscription Never gets called")
self.openURLSubject.sendNext(reminderURLRequest)
})
return true
}
}
let RemindersLoadedSignal = RACSubject()
class RemindersViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
}
func bindViewModel(){
sharedAppDelegate().openURLSubject.subscribeNextAs { (request:OpenURLRequest) -> () in
println("got url request")
}
RemindersLoadedSignal.sendNext(NSBoolTrue)
}
}
I dont understand how the subscription in didFinishLaunchingWithOptions works and the one in application:openURL:... doesnt.
I ended up loading the view with doNext and Zipping the signal with the RemindersLoadedSignal.
If you see any potential problems with that please let me know.
Thanks
.doNext { (_:AnyObject!) -> Void in
if let myTabBar = self.window?.rootViewController as? UITabBarController {
myTabBar.selectTabWithClass(RemindersViewController.self)
}
}
.zipWith(RemindersLoadedSignal)
I'm working on an iOS app using Xcode 6 and Swift. I'm working with storyboard, so I don't have to instantiate a NavigationController in AppDelegate.
But in my applicationDidFinishLaunching, I instantiate a controller to control Philips Hue
var window: UIWindow?
var phController:PHController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.phController = PHController()
return true
}
In this PHController I have a heartbeat function, which is checking all 10 seconds if the connection to the Philips Hue Bridge is still alive.
If not (and this could happen all the time, INDEPENDENT from where the user is currently in the app), I would like to pop a view controller (SearchForNewBridgeViewController).
The question is:
How can I pop/present modally a ViewController from PHController class instantiated when the app did finish launching?
My idea is to instantiate the PHController with the navigationController:
self.phController = PHController(self.navigationController)
But my project is as I mentioned Storyboard based, so I don't have a navigationConntroller in my AppDelegate
Ok I found a solution :)
Solution:
Instantiate my controller and give AppDelegate as argument:
var window: UIWindow?
var phController:PHController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.phController = PHController(delegate:self)
return true
}
Initializer of PHController:
var delegate:AppDelegate?
init(delegate:AppDelegate) {
self.delegate = delegate
...
}
Present SearchForNewBridgeViewController modally from PHController:
func showSearchForNewBridge() {
let storyboard = UIStoryboard(name: "Main", bundle: nil);
var searchForNewBridgeViewController = storyboard.instantiateViewControllerWithIdentifier("searchForNewBridge") as SearchForNewBridgeViewController
var navigationController = self.delegate!.window!.rootViewController as UINavigationController
navigationController.presentViewController(searchForNewBridgeViewController, animated: true, completion: nil)
}
It's working perfectly for me