0

I've a ViewController which is named mapViewController. Inside that controller I've a button which is a play button. If the button is clicked a boolean named "Play" will change from false to true.

Let's jump to the point of this thread:

Once I press the button, I want the boolean to be changed to true. If the user leaves the application. (Entering the background) I want to print out a text which displays that. (I'll use this for other purposes as soon as I get an idea how this works.)

So, let's take a look at my AppDelegate

func applicationDidEnterBackground(_ application: UIApplication)
    {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

        let mapVC = UIApplication.shared.delegate as! MapViewController

        if (mapVC.play == true)
        {
            print("The play-bool is true, and application did enter the background")
        }


    }

Once I press the button, and leaves the application I'm getting an error which looks like this:

Could not cast value of type 'MyDogwalk.AppDelegate' (0x28093e230) to 'MyDogwalk.MapViewController' (0x104f99d98).

warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.

As you can see on my code, I'm trying to get a boolean from a ViewController, and check it's statement inside my AppDelegate.

I'll use this information to track locations once the phone is in the background, but as this is my first time. I need/want to understand how this actually works, and how I can do this.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Putte
  • 328
  • 2
  • 17
  • 3
    Unrelated, but you can use just `if mapVC.play` – Robert Dresler Mar 12 '19 at 16:49
  • How are you expecting to get the MapViewController from the App Delegate? `UIApplication.shared.delegate` will return the current `AppDelegate`, so the class you're currently in. – TomQDRS Mar 12 '19 at 16:50
  • First: you can't cast delegate to a UIViewController (`delegate as! MapViewController`) its obviously incorrect. Second: is `MapViewController` root or the visible view controller? In addition I would encourage to avoid accessing the view controller from the `AppDelegate`, check: https://stackoverflow.com/questions/24675907/how-to-access-applicationdidenterbackground-from-viewcontroller – Ahmad F Mar 12 '19 at 16:55
  • 1
    @TomQDRS I'm not expecting anything. I've tried some ways, but could not find a good answer. So this is where I'm currently. And I had no idea that code will return the current AppDelegate, otherwise I would not use that kind of code. Sorry. :) – Putte Mar 12 '19 at 16:56
  • This makes no sense: `let mapVC = UIApplication.shared.delegate as! MapViewController`. Your app delegate is AppDelegate, _not_ MapViewController. What are you trying to do with that line? – matt Mar 12 '19 at 17:02
  • @Sh_Khan I really appreciate your answer. In my opinion, all answers is good answers. And I'm sorry for all those downvotes. - Same with my thread, people is just down voting without giving a reason why – Putte Mar 12 '19 at 17:10
  • @Sh_Khan I think you got downvotes because as an expectation from an answerer with such a reputation is to give a "good" answer, not that "workable" one. For me I can see your -deleted- answer and I think its not a good idea to follow... However, I know that it is bad most of the time to get downvote without a reason. I hope that nothing personal, we should be good with each other; Although the community sometimes makes us frustrated, we still need to be kinds. So, as mentioned, in my humble opinion, to avoid such a case, try to post good answers instead of workable ones. Don't rage and chill! – Ahmad F Mar 12 '19 at 17:19
  • @AhmadF How about my thread, haha. Beginner in SWIFT, and ppl expect me to know everything lol – Putte Mar 12 '19 at 17:21
  • @Putte I don't usually downvote (I didn't do it here), but I think that one of the reasons could be related to why you got downvoted because probably you were able to find a result (even better than the one you tried to follow) if you invested more time to search for it; For me still not a good reason to always downvote... Anyway, hope you got your answer :) – Ahmad F Mar 12 '19 at 17:25
  • @AhmadF Ofcourse, I get that point. But when I've no idea what to search on. (Since I had no idea I could use Notification Center, I do not like that decision of down voting. - And absolutely not when someone like me, with very low reputation. Since too many downvotes will lead into not asking questions anymore. And a lot of people cannot move on in their career, and become a better programmer without any help. But well well, that's fine for me. :) – Putte Mar 12 '19 at 17:29

2 Answers2

4

Please don't try to access controllers from the AppDelegate, that is not its intended purpose.

You can check whether an application will enter into the background from anywhere, if you register your current ViewController to the correct NSNotification. Then you will define a function that is executed when the App enters the background state, in which you will be able to print out your text.

Please take a look at https://stackoverflow.com/a/9012734/4442731 for how to do this. A swift solution is in the answer below the linked answer. This code needs to be in your MapViewController.

TomQDRS
  • 875
  • 1
  • 7
  • 20
  • Or maybe this one: https://stackoverflow.com/a/51589649/5501940 ;) – Ahmad F Mar 12 '19 at 16:59
  • So, what you're saying is: I do not need to do this kind of stuff in the AppDelegate? I can just do this inside my MapViewController? Is that correct? Just a question: When should I do stuff in the AppDelegate? – Putte Mar 12 '19 at 17:02
  • @Putte Well, really depends on what "kind of stuff" you mean. If you're planning to use the `boolean` set by the play button in other controllers, you should save it for example to `UserDefaults`, like Robert's answer suggests, or a Singleton object. Anything dependant on your `UIViewController`'s state should be done inside said controller. The `AppDelegate` can be used for basic operations that should happen regardless of controller state on important App events, like start-up. – TomQDRS Mar 13 '19 at 08:08
2

Maybe you should rethink your application:

  • One way is adding observer for certain Notification name like UIApplication.didEnterBackgroundNotification. So you'll be noticed in your UIViewController class that your app goes to background
  • Or if play is something which should be stored, you can use UserDefaults, FileManager or some database for storing this value, and then you can retrieve this value in applicationDidEnterBackground(_:)
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
  • The thing is, I'm not going to print something out later on. I've just done it for now till I get a good idea how I can perform what I need. Later on, I will retrieve current location of a user in the background (Once that button is pressed), and when I re-enter the application, I need it to update the current array and insert the new values which I will be able to use to draw a polyline. – Putte Mar 12 '19 at 17:04