How to understand Objective-C AppDelegate method application:didFInishLauchingWithOptions? - ios

I am new in iOS development, I saw the function
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
As I know, to declare a function is
-/+(return type)function_name: (param type)param
So what is the function name of the function mentioned above?

Here name of the function is application but its mostly called application didFinishLaunchingWithOptions. Its called first when the app is launched.

Related

ios - signal function with SIGPIPE and SIG_IGN

I have joined in a old project and I found this line
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
signal(SIGPIPE, SIG_IGN);
....
}
I have found in docs this:
/*
* For historical reasons; programs expect signal's return value to be
* defined by <sys/signal.h>.
*/
But I'm still confused as to what the purpose of that line is.
From Apple's documentation:
When a connection closes, by default, your process receives a SIGPIPE signal. If your program does not handle or ignore this signal, your program will quit immediately.
Ignore the signal globally with the following line of code:
signal(SIGPIPE, SIG_IGN);

xcode 7 warning: Null passed to a callee that requires a non-null argument

After updating to xcode 7 a warning
Null passed to a callee that requires a non-null argument
started appearing at place
[self application:application openURL:url sourceApplication:sourceApplication annotation:nil];
this method is called manually in method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
I know this warning is appearing because now annotation parameter cannot be nil now from this answer but I don't have any idea what to pass there as data type is id or there is any other way that I can removing this warning.
As it seems you don't actually need the annotations:
Extract the body of your application:openURL:sourceApplication:annotation: to a new method.
Implement application:openURL:sourceApplication:annotation: by calling the new method.
In your application:didFinishLaunchingWithOptions: also call the new method.

Starting point of ios application

if write something in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"Starting point 1");
}
main.m
int main(int argc,char * argv[])
{
......
NSLog(#"Starting point 0");
}
Which one is more useful main.m or appDelegate.m one and in which scenerio.
This is an interesting article that explains the app launch sequence.
http://oleb.net/blog/2011/06/app-launch-sequence-ios/
As a resume of the article the conclusion is:
Besides application:didFinishLaunchingWithOptions:, there are several more entry points for custom code during the launch sequence (none of which are usually needed):
Directly in main() before UIApplicationMain() is called.
The init method of a custom UIApplication subclass.
The initWithCoder: or awakeFromNib methods of our application delegate if it is created from a NIB file (the default).
The +initialize methods of our application delegate class or a custom UIApplication subclass. Any class receives an +initialize message before it is sent its first message from within the program.
Note that this sequence only happens at the actual launch of an app. If the app is already running and simply brought back from the background, none of this occurs.
You should use your UIApplicationDelegate, not the main.m.
The didFinishedLaunching method is a good (but not the only) starting point.
Only there your are sure all the iOS specific code is loaded correctly.
In the main the load could have had an error, the line would be executed in the main but not in the didFinishedLaunching method.
The main() method is the very first thing that is called in terms of iOS applications however it is a general rule never to touch the main() function in iOS programming.
The
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions
occurs after a successful launch of the app and should be used for any processes you need to do at the start of the application.

NSURLSession vs Background Fetch

Ok, so I was looking at the SimpleBackgroundFetch example project, and it uses the following in the App Delegate:
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:someTimeInSeconds];
//^this code is in didFinishLaunchingWithOptions
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
//do something + call completionHandler depending on new data / no data / fail
}
So, basically I assume, that I call my app's server here, to get some data.
But then I saw the NSURLSession docs, and it had methods like these
– downloadTaskWithURL:
and it said the following:
This API provides a rich set of delegate methods for supporting
authentication and gives your app the ability to perform background
downloads when your app is not running or, in iOS, while your app is
suspended.
So what's the difference between these two APIs? And what should I use if I want to download some data from my app's server every now and again?
I just wasn't sure about the difference between the two, so I just thought I should get my doubts clarified here. Go StackOverflow!
These are completely different things.
Background Fetch: System launches your app at some time (heuristics) and your job is to start downloading new content for user.
NSURLSession: Replacement for NSURLConnection, that allows the downloads to continue after the app is suspended.
The application delegate is for storing the completion handler so you can call it when your download is finished.
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
NSLog(#"Handle events for background url session");
self.backgroundSessionCompletionHandler = completionHandler;
}
and call the handler
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
WebAppDelegate *appDelegate = (WebAppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.backgroundSessionCompletionHandler) {
void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = nil;
completionHandler();
}
NSLog(#"All tasks are finished");
}
NSURLSession:Allows to uploading and downloading in the background mode and suspend mode of application
Background Fetch:Happens according to volume of the data and duration of previous data transferring process.Only last for 30s.
So you confirm a background URLSession endowed with a delegate should be called, while a normal dataTask with block may not be?

Do I initialize the viewController when I receive UIApplicationLaunchOptionsLocationKey in app didFinishLaunchingWithOptions?

I'm creating an app which listens to significant location change events and in case the app gets terminated then the iOS launches the app with UIApplicationLaunchOptionsLocationKey set.
So, the documentation says to create a new location manager and register for location updates again. However, doesn't mention if I'm supposed to initialize my viewController (as I do in normal app launch as well)? My view controllers initialize in viewDidLoad but are created in appDidFinishLaunchingWithOptions.
Any idea how much time does OS provides to the App for location update handling? My app needs to make a webservice request if the location change indicates an interested location for the app.
Thanks
You should consider moving your initialization code to a new method, something like initializeViews. This method would check to make sure the views haven't been initialized and then initialize them. You would call this method from application:didFinishLaunchingWithOptions: and applicationWillEnterForeground:, but the call in application:didFinishLaunchingWithOptions: would only occur if the application wasn't going to the background.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
if([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
[self initializeViews];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self initializeViews];
}
- (void)initializeViews {
if(!viewsAreInitialized) {
...
viewsAreInitialized = YES;
}
}

Resources