Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup dialog doesn't appear when app is in background #140

Closed
kabiryeshe opened this issue May 8, 2017 · 13 comments
Closed

Popup dialog doesn't appear when app is in background #140

kabiryeshe opened this issue May 8, 2017 · 13 comments

Comments

@kabiryeshe
Copy link

kabiryeshe commented May 8, 2017

Please fill out this template when filing an issue.
All ℹ symbols should be replaced with information on the issue.
Please remove this line and all above before submitting.

Thanks for this library. It's pretty useful. Here is the bug I am facing:

Report

Environment

Please provide information on your development environment, so we can build with the same scenario.

  • Mac OS version (e.g. 10.12): 10.11.6
  • Xcode version (e.g. 8.0): 8.2.1
  • PopupDialog version (e.g. 0.5.0): 0.5.4
  • Minimum deployment target (e.g. 9.0): 9.0
  • Language (Objective-C / Swift): Swift
  • In case of Swift - Version (e.g. 3.0): 3.0

Dependency management

If you are not using any dependency managers, you can remove this section.

Please note: If you are using CocoaPods with Xcode 8, CocoaPods 1.1.0 is required.

  • Dependency manager (e.g. CocoaPods): Cocapods
  • Version (e.g. 1.1.0): 1.2.0

What did you do?

Present a popup dialog when app is in background.
This was first observed when a network call finished when app was in background.
Second time to simulate it, a timer was used to fire when app was in background.

What did you expect to happen?

When app comes back to foreground (appWillEnterForeground:), popup dialog should be present
on the screen.

What happened instead?

Popup Dialog was not present on the screen.

Project that demonstrates the issue

Let me know if this is needed, I will upload one.

ℹ In complex cases, it might be useful to link to a sample project. If you don't provide an example, you can delete this section.

@kabiryeshe
Copy link
Author

kabiryeshe commented May 8, 2017

I tried debugging this issue. PopupDialog's viewDidLoad and viewWillAppear get invoked.
Somehow, viewWillDisappear is also called when app is in background. Not quite sure if it's a feature or bug. :P

When I tried simulating the same scenario i.e. presenting a view controller (lets say VCB) from another (VCA) when the app was in background, it works as expected. VCB is present on screen when app comes in foreground.

@kabiryeshe kabiryeshe reopened this May 8, 2017
@mwfire mwfire changed the title Popup diloag doesn't appear when app is in background Popup dialog doesn't appear when app is in background May 9, 2017
@mwfire
Copy link
Member

mwfire commented May 9, 2017

Hey there! Phew, that's a tricky one. It actually should be avoided to do UI updates when the app is in background, this can lead to weird side effects. Does this work with UIAlertController?

@kabiryeshe
Copy link
Author

Hi Martin,
Thanks for a quick response.

The behavior with UIAlertController is the one that I expected:
When app comes back to foreground (appWillEnterForeground:), alert controller is present
on the screen.

Just one thing that's interesting though. As timer to show alert is already fired when the app is in background, there should have been an UIAlertController the moment app comes to foreground. But contrary to this expectation, the transition with animation can be observed when app comes to foreground. It seems that this action is queued up and executed when app comes to foreground.

@stale
Copy link

stale bot commented Dec 1, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Dec 1, 2017
@stale stale bot closed this as completed Dec 8, 2017
@OhadMaor-VIA
Copy link

OhadMaor-VIA commented Nov 22, 2018

@mwfire , This issue still exist and can be easily reproduced.
I am also facing the same issue and it appears to be an issue with this library, should I open another ticket (since this one is closed) ?

When coming back to foreground you can see the PopupDialogVC just for a 1/100 sec and it disappears and when you use memory graph, you can see that the instance of PopupDialogVC is still in the memory even though it isn't visible. Did you also check memory graph for that zombie instance @tushargarg ?

We should come up with a solution for this ASAP because the use case of an async request -> user goes into background -> user comes into foreground after a while is a common behaviour.

@mwfire mwfire reopened this Nov 22, 2018
@stale stale bot removed the wontfix label Nov 22, 2018
@mwfire
Copy link
Member

mwfire commented Nov 22, 2018

Hey there!
Can you confirm you are presenting the dialog from the main thread?
Can you please provide a small example project, as it works for me in the PopupDialog example.

Thx a lot :)

@OhadMaor-VIA
Copy link

OhadMaor-VIA commented Nov 25, 2018

Sure @mwfire, basically the issue is when doing a server async request.

Inside the PopupDialog example project:

func showImageDialog(animated: Bool = true) {
...
...
let url = URL(string: "https://pastebin.com/7F1cQbqM")!
        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            DispatchQueue.main.async {
                self.present(popup, animated: animated, completion: nil)
            }
        }
        task.resume()
 }

and once you tap on the Show Image Dialog button, tap the home button, wait a few secs and open the app. You will see that the alert shows for a 1/100 of a sec and disappears.
Also, if you'll tap on Debug Memory Graph inside Xcode and filter Popup, you will see that the Popup instance is still in memory.

In contrast, create a new storyboard with an empty ViewController and replace the below code:

func showImageDialog(animated: Bool = true) {
...
...
let url = URL(string: "https://pastebin.com/7F1cQbqM")!
        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            DispatchQueue.main.async {
                let storyboard = UIStoryboard(name: "YourName", bundle: nil)
                let controller = storyboard.instantiateViewController(withIdentifier: "YourIDName")
                self.present(controller, animated: true, completion: nil)
            }
        }
        task.resume()
 }

Do the same use case, tap the home button and open the app after few secs and you will see that the ViewController IS presented unlike PopupDialog instance.

Please let me know if anything isn't working as explained. Thanks!

@mwfire
Copy link
Member

mwfire commented Nov 25, 2018

Hey there, can you do me a favor and give it a shot with disabling animations when the app is in background, something like this

func doBackgroundWork() {
        let url = URL(string: "https://pastebin.com/7F1cQbqM")!
        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            DispatchQueue.main.async {
                self.showImageDialog(animated: UIApplication.shared.applicationState == .active)
            }
        }
        task.resume()
}

Does that work for you?

@OhadMaor-VIA
Copy link

OhadMaor-VIA commented Nov 25, 2018

It sure does. I've tried everything besides that..
It's a great workaround but I think we should implement a build-in mechanism for that.

Thanks again!

@mwfire
Copy link
Member

mwfire commented Nov 26, 2018

@OhadMaor-VIA, ok cool. So we pinned it down to animation collision when the app comes to foreground. I will see if it can be added to the library.

@ivulyov90
Copy link
Contributor

ivulyov90 commented Nov 28, 2018

Hey @mwfire
I also investigated to this issue.
animated: UIApplication.shared.applicationState == .active doesn't help if app calls present() function in foreground and does drawings in background.
Also I found how two fix it with "one line" change.
We need to change "in" animation completion handler in all TransitionAnimator classes.
For example ZoomTransition:

         case .in:
            to.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
                self.to.view.transform = CGAffineTransform(scaleX: 1, y: 1)
            }, completion: { completed in
                transitionContext.completeTransition(completed)
            })

Should be replaced with:

        case .in:
            to.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
                self.to.view.transform = CGAffineTransform(scaleX: 1, y: 1)
            }, completion: { completed in
                transitionContext.completeTransition(true) // "completed" is false as animation fails if app is in background
            })

@ivulyov90
Copy link
Contributor

ivulyov90 commented Nov 28, 2018

I opened PR with the fix. It will be great to get it with a new version asap.
Thanks!

@mwfire mwfire removed the improvement label Dec 2, 2018
@mwfire
Copy link
Member

mwfire commented Dec 2, 2018

Included in
https://github.com/Orderella/PopupDialog/releases/tag/0.9.2

Thanks @ivulyov90

@mwfire mwfire closed this as completed Dec 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants