Does firebase functions keep running after dissiming a view-controller - ios

I am a newbie in iOS development/firebase.
I have two view controller,
the first one does nothing expect performing a segue to the second view-controller
The second the view controller I have two buttons,the firstone is (back) which dismiss a view controller and the second button(up) have the following code
Database.database().child(“posts”).setValue(1)
1- If I have an extremely bad internet connection, and I pressed on up button then immediately pressed on back,
Does the code for uploading data for firebase stop on continue?
2- After pressing up, I immediately go to background and dismiss the app, will it continue setting the data?

All database operations are handled on another thread that's not related to any UI elements in your app. As long as your app is running, database operations will continue until complete.
If the app is no longer running, database operations will stop. If database persistence is not enabled, all of that pending work will never complete. If database persistence is enabled, then the SDK will try again to synchronize the writes that didn't complete previously.

Related

Load entire application at start up

I have a tabbed iOS application with each of the tabs having some sort of json request so the view loads ever so slightly slowly. I want to remove that lag completely so I'm wondering if there is a way to call the ViewDidLoad function from each of the classes during the login phase of the application.
if (login == "Success") {
UserDefaults.standard.set(true, forKey: "isUserLoggedIn");
UserDefaults.standard.synchronize();
DispatchQueue.main.async {
// Load all resources here
}
}
I can understand this can be bad practice if the app is very large, but I think in this scenario the app isn't huge, but the lag between the view controllers is enough to be annoying. I would rather have the user wait at the start for 3-5 seconds whilst everything loads, and have a smooth experience once inside. Is there a way to do this?
You shouldn't call the lifecycle functions of the viewcontroller for yourself. The viewDidLoad function will be called when the view has been loaded.
Apple: This method is called after the view controller has loaded its view hierarchy into memory.
So calling let _ = viewController.view will trigger the view creation and the call of this function.
But i think it's much better to have a startup phase instead. Think about a 'startup'-screen that downloads everything you need (with maybe a spinner and a text) and moves automatically to the content (the tabbar controller) when done. That may also fix the problem of a low network connectivity (think about a download that take a minute for example). You may display that screen modally above or as screen before the tabbbar controller.
If you don't like the idea of a startup phase you may also design your ui responsive. Start the download whenever needed / regularly and update your ui according to the results when ready. The ui will be fast then, but uses last known data. The meaningfulness and implementation depends on your content.
Update
On second thought: If you already have a server login screen, why not download the content directly after the successful download as part of the login? Users do not know if you are still checking the login or downloading some necessary data. You may say that login is only successful if server login AND download are finished successfully.

Having trouble with AppDelegate didFinishLoadingWithOptions execution order/timing

I'm having an issue with this code (I have it in didFinishLaunchingWithOptions). I need it to finish executing the code inside before the app continues because it sets up some critical things in core data. It sends this to the background though and starts running the rest of the app and it doesn't finish quick enough for the data to be usable.
DataManager.getDataWithSuccess { (data) -> Void in
//code to execute here
}
How can I force the app to wait for this code to finish before moving on?
You shouldn't block the didFinishLaunchingWithOptions method from returning so that it can wait on an asynchronous task. It's crucially important to note that iOS applications are only given a limited amount of time to complete launching before the application is killed by the operating system.
An approach I have used in the past when waiting on asynchronous things to happen that need to happen before I really launch my app is to create a LaunchViewController. The interface for this view controller matches perfectly to the app's splash screen. From an end-user perspective, you can't even tell we've left the splash screen.
Here, we do any set up code such as asking your DataManager to get data. Then, when it (and any other set up actions) completes, you simply present the next view controller in much the same way you'd move between any other view controllers.
A huge positive side effect here is that you can have much nice looking animations from your splash screen into the first screen of your application.

background methods are not stopping after viewWillDisappear/ Dealloc

First of all Check This to understand what i am doing
I did not get my answer in above question & still waiting for it.
Now new porblem is that when i click on back button using following code, methods of last ViewController are still running. It will use memory & keep processing untill it gets response(that`s what i want to do but if user press back then i want to stop all methods)
[self.navigationController popViewControllerAnimated:YES];
How do i stop it?
You need to do [getTryAgainTask cancel] (assuming getTryAgainTask is of type NSURLSessionDownloadTask) before you pop this controller. The download task is asynchronous and runs irrespective of the controller (that fired it) being deallocated. This might cause retain loops, leading the app to eventually crash. The code as of now, will go into an infinite loop. A better solution would be to keep a tab on the number of retries (say 3 times) and then prompt the user about the problem, asking if he/she would like to try again.

Display loading view after login in ios 3 seconds

I am trying to display a new view in IOS after login in my application. I also want to display this view when I start the application if the user is already logged in this app.
Now, if I start the application the first time I have the login view and I can write my user name and my password. when I press send button(login) the next controller starts. I would like to set for 2 or 3 seconds one view while I am downloading the information from the web service. I don't care if the information comes faster than the two seconds because I want to wait this time. I save the user information in NSUserdefaults.
Next time I start the app I already have the information and I go directly to the next viewcontroller without see any login view. So I want to watch the loading view.
I use AFNetworking to consume my web services.
You have two options, it seems a little arbitrary to show it for 2 seconds, but you can present the view and then:
[myView performSelector:#selector(setHidden:) withObject:[NSNumber numberWithBool:YES] afterDelay:3.0];
Or what you probably should do is hide the view or set it to nil within the completion block of your AFNetworking Call, that way if the call takes longer than 2-3 seconds, the view won't disappear
You can call the method for hiding view after delay using this:
[self performSelector:#selector(hideView) withObject:nil afterDelay:3.0];
Here is an idea, using GCD:
Store the login information into keychain (NSUserDefaults are just plain unsafe for passwords!) and dismiss the login window immediately after it is saved.
When the loding view is shown, create a dispatch group and submit your login and download logic there. (com.example.login thread)
Use NSTimer (or any appropriate logic) to wait for 3 seconds, then spawn another thread in GCD (com.example.login-wait thread), call dispatch_group_wait to block that thread until the com.example.login thread is done, and submit a block back to the main queue to switch views.
I used this login in multiple applications and it looked fantastic.

Strategy to launch a task - and avoid race conditions - from the App Delegate

I'm developing a small app on top of core data. At startup, I need to launch a maintenance task - fast but important -. To run this task, the app delegate must open a UIManagedDocument, and perform various checks on it. The app views must not start until the checks are completed. Because opening a UIMD is asynchronous, the app delegate isn't done when the first UIview tries to access the doc. The application then crashes due to a race condition because the app delegate and the view are trying to open the doc at the same time, while the doc state isn't yet finalised.
I'm using a storyboard, so segues are pretty much in control of the OS... Next time, I'll do it all manually..
What would be your recommendations ?
Note:
1)I can not perform the task when the app. goes into background state, because if it is brought back up again, avoiding inconsistent states between the underlying database and what's displayed in the view will be very tedious.
2)For the same reasons, performing the maintenance task during normal execution is not easily done.
3) All views access the UIMD via a singleton, according to the code proposed here
Setting a mutex lock in the UIView isn't my preferred route, because the screen remains black - no data -, while displaying the tab bars, until it is released by the app delegate.
Is there a way to have the app delegate wait for a signal before it hands the control over to the UIViews ? In this case, are there any gotchas ? I suspect this is probably not the recommended way to do, and iOS might kill the app if the delegate stays too long waiting for the maintenance task to complete. What would be "too long" in this case?
You could do it more elegant way. The first view the user will see must be some kind of SplashView - just an image with progress indicator. It should stay on top while your task is going on. It's not too important how you're showing this view. You can set it as the first in your storyboard or just create it manually in applicationDidFinishLaunching message.
Then in your task send a NSNotification when it's about to finish and in the observer in your AppDelegate just hide your SplashView and present your first view with valuable content.
You can even add some visual effects for transition between those views and your app will look really great! :)

Resources