ios determine how an app is launched - iphone

Is there any way to determine "how" an app is launched or made active (i.e. homescreen tap, four finger swipe, siri, etc...)?
There's this thread which is similar (Determining whether iOS application was launched via Siri), however not too many answers in this. There's also this for Mac OSX (How can a Mac app determine the method used to launch it?) but I need something similar for iOS.
I've also skimmed through this (https://developer.apple.com/library/ios/DOCUMENTATION/iPhone/conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW3) though I coudn't find anything that recognizes "how" the app was launched.
Thanks in advance.

You can figure out that an app was launched from a URL in another application using the AppDelegate method:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation { }
Additionally, application:DidFinishLaunchingWithOptions: has options, which are keys that you can find here that tell you reasons why the app launched.
Those keys are:
NSString *const UIApplicationLaunchOptionsURLKey;
NSString *const UIApplicationLaunchOptionsSourceApplicationKey;
NSString *const UIApplicationLaunchOptionsRemoteNotificationKey;
NSString *const UIApplicationLaunchOptionsAnnotationKey;
NSString *const UIApplicationLaunchOptionsLocalNotificationKey;
NSString *const UIApplicationLaunchOptionsLocationKey;
NSString *const UIApplicationLaunchOptionsNewsstandDownloadsKey;
NSString *const UIApplicationLaunchOptionsBluetoothCentralsKey;
NSString *const UIApplicationLaunchOptionsBluetoothPeripheralsKey;
You can check for them with if statements when the app launches.

Related

is there a way to differentiate the IOS application launched using custom url and on clicking the application icon?

I am developing a ios application. When i launch the application it should open the root view. If i am launching the application using custom url from a website, it should initialize with another nib file. Can someone help me with the problem.
Once again thank you for the answers.
In your app delegate you have to implement:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
This will be called if your app is opened via URL scheme. In there you can react appropriately.
You can find the documentation here.
You have to implement open url in app delegate
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if (!url)
{
return NO;
}
NSString *URLString = [[url host]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return YES;
}
Here is a nice link you can follow link`

Not getting the Device Token on iPhone iOS 5.1 Xcode 4.3.1

Like many i struggle with Push notifications.
Now, I got almost everything working. I have the certificates, keys and all in place. I even ran it the first time and got the famous alert box asking me if I want to allow push notifications and clicked OK.
But I never, ever got the printout of the Device Token.
I put a break point in the method below, but never stops there.
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWith:DeviceToken:(NSData *)deviceToken {
NSString *str = [NSString stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(#"%#", str);
}
Any suggestions?
For getting device token use
(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWith:DeviceToken:(NSData *)deviceToken
{
NSString *str = [deviceToken description];
NSLog(#"%#", str);
}
NSString *str = [NSString
stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(str);
I had this problem but this code worked for me
If you run the app in the simulator, the didFailToRegisterForRemoteNotificationsWithError: method will be called as push notifications are not supported in the simulator.

How can I identify UILocalNotification and snooz it again?

I am developing an alarm app and having some issues and snooz and repeatation of alarms, I am making a Class having name, time and other alarm options below
int alarm_id;
NSString *nameOfAlarm;
NSString *timeOfAlarm;
NSString *repeatAlarm;
NSString *soundOfAlarm;
NSString *snoozOfAlarm;
NSString *soundFadeInOfAlarm;
NSString *volumeOfAlarm;
NSString *vibrationOfAlarm;
Now I am saving above values to my Sqlite database, and at same time I am setting notification to iOS, when notification fires the, then I want to snooz and also want same alarm on different days,
I don't want exact code, but a concept or view how to do that ?
Help .
You can use UILocalNotification's userInfo to store a unique identifier for each notification.
Take a look at the UILocalNotification documentation.

Finding list of installed apps on iphone

Is it possible to programatically find out name of all apps installed on my iOS device ?
Is there any API available for same ?
Thanks for the help
No, on iOS applications has no access to information of/about other applications due to sandboxed environment.
Yes it is possible to get list of all installed app
-(void) allInstalledApp
{
NSDictionary *cacheDict;
NSDictionary *user;
static NSString *const cacheFileName = #"com.apple.mobile.installation.plist";
NSString *relativeCachePath = [[#"Library" stringByAppendingPathComponent: #"Caches"] stringByAppendingPathComponent: cacheFileName];
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent: #"../.."] stringByAppendingPathComponent: relativeCachePath];
cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
user = [cacheDict objectForKey: #"User"];
NSDictionary *systemApp=[cacheDict objectForKey:#"System"];
}
systemApp Dictionary contains the list of all system related app
and user Dictionary contains other app information.
Not from the device. However, from the desktop you could peek into the iTunes library.
There are ways to do this without a jailbroken device and not get your app rejected.
1. get a list of currently running processes see this SO answer. You will need to translate from process name to app name.
2. Check to see if any apps have registered a unique URL scheme with UIApplicationDelegate canOpenURL. There are a few sites cataloging known url schemes, this is the best one.
If an app is not currently running and does not register a custom url scheme then it will not be detected by these methods. I am interested in hearing a method that will be allowed in the app store that works better than this.
try this, it will work even with non-jailbroken devices:
#include <objc/runtime.h>
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector=NSSelectorFromString(#"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];
SEL selectorALL = NSSelectorFromString(#"allApplications");
NSLog(#"apps: %#", [workspace performSelector:selectorALL]);//will give you all **Bundle IDS** of user's all installed apps
You can do it by checking whether an application is installed or not by using canOpenURL method or by checking the background processes and matching them with the name of the app you are interested in.
You can use runtime objective c to get the list of all installed apps. It will give you an array of LSApplicationProxy objects.
Following is a code snippet that prints Name of all applications installed in your device.
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:NSSelectorFromString(#"defaultWorkspace")];
NSMutableArray *array = [workspace performSelector:NSSelectorFromString(#"allApplications")];
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
for (id lsApplicationProxy in array) {
if(nil != [lsApplicationProxy performSelector:NSSelectorFromString(#"itemName")]){
[mutableArray addObject:[lsApplicationProxy performSelector:NSSelectorFromString(#"itemName")]];
}
}
NSLog(#"********* Applications List ************* : \n %#",mutableArray);
Don't forget to include <objc/runtime.h> .

Lauching App with URL (via UIApplicationDelegate's handleOpenURL) working under iOS 4, but not under iOS 3.2

I have implemented UIApplicationDelegate's
application:didFinishLaunchingWithOptions:
and
application:handleOpenURL:
according to specification, i.e.,
application:didFinishLaunchingWithOptions:
returns YES
and
application:handleOpenURL: opens the URL.
The code works under iOS 4 (in both cases, i.e., when the app is launched and when it becomes active from suspended state). However, the code does not work under iOS 3.2.
I give an answer to my own question. Finding out the solution took me a while and was quite frustrating. If you do an internet search you find some partial answers, but it still took me a while to work out the following solution and I do hope it adds some clarity.
So first, the recommended behavior of your app appears to be the following (see Opening Supported File Types in iOS Ref Lib):
Do not implement applicationDidFinishLaunching: (see the note at UIApplicationDelegate).
Implement application:didFinishLaunchingWithOptions: and check the URL, return YES if you can open it, otherwise NO, but do not open it.
Implement application:handleOpenURL: and open the URL, return YES if successful, otherwise NO.
In iOS 4, passing an URL to an app results in one of the following two behaviors:
If the app is launched then application:didFinishLaunchingWithOptions: is called and application:handleOpenURL: is called if and application:didFinishLaunchingWithOptions: returned YES.
If the app is becoming active from suspended state then application:didFinishLaunchingWithOptions: is not called but application:handleOpenURL: is called.
However, in iOS 3.2 it appears as if application:handleOpenURL: is never called! A hint that the behavior is different under iOS 3.2 can be found in Handling URL Requests. There you find that application:handleOpenURL: is called if application:didFinishLaunchingWithOptions: is not implemented, but applicationDidFinishLaunching: is implemented. But application:handleOpenURL: is not called if application:didFinishLaunchingWithOptions: is implemented.
Hence, one solution to make the code work under 3.2 and 4.0 is:
Open the URL in application:didFinishLaunchingWithOptions:, but then return NO to prevent that application:handleOpenURL: is called.
Open the URL in application:handleOpenURL:, in case you are under 4.0 and the app was in suspended state.
I found this solution in another post, but I was confused, because it contradicted the recommendation in iOS Ref Lib documentation (namely that we should return YES in application:didFinishLaunchingWithOptions:). (At that point I did not realize that the documentation contradicts it self).
I believe that the current iOS 4.0 behavior will be the future behavior I prefer the following solution:
Do not implement applicationDidFinishLaunching:.
Implement application:didFinishLaunchingWithOptions: and check the URL, return YES if you can open it, otherwise NO, but do not open it. If we are on 3.2, open the URL.
Implement application:handleOpenURL: and open the URL, return YES if successful, otherwise NO.
So in summary, I implement the iOS 4 behavior and added the following line to application:didFinishLaunchingWithOptions:
if([[[UIDevice currentDevice] systemVersion] hasPrefix:#"3.2"]) {
[self application:application handleOpenURL:url];
}
which make the code work under 3.2.
application:handleOpenURL: is now DEPRECATED.
As of iOS 4.2, you can use this for opening URLs:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
Documentation:
https://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html
I started writing application which used Dropbox api. To understand concept, I ran a sample application using my Key/secret mentioned at dropbox/developer documentation.
Once sample app started working, I used same key/secret values for my application.
For sample app, implementation of handleOpenURL (or openURL on iOS 4.2) gets executed as expected. For some odd reason, it wasn't the case for my app. My app entered background in order to show login screen and authentication page of dropbox. After successful login and authentication, my app never entered foreground. It was true for both platform Simulator and device (iPad)
I tried almost everything listed on internet including this post. Thanks. There was NO success, though.
At last, it STARTED working for my application when I did following:
On simulator, select "iOS Simulator --> Reset Content and Settings", and reset.
On device, I deleted sample application related executable and which in turn delete cache associated to it.
Add the following to the end of application:DidFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
if (url != nil && [url isFileURL]) {
return YES;
} else return NO;
} // End of application:didFinishLaunchingWithOptions:
// New method starts
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
mvc = [nc.viewControllers objectAtIndex:0];
if (url != nil && [url isFileURL]) {
[mvc handleOpenURL:url];
}
return YES;
}
where mvc is my main ViewController, and nc my navigation controller.
Then in the MainViewController, do something like this:
- (void)handleOpenURL:(NSURL *)url {
[self.navigationController popToRootViewControllerAnimated:YES];
// Next bit not relevant just left in as part of the example
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error;
NSDictionary *dictionary = [[NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error] objectAtIndex:0];
[self managedObjectFromStructure:dictionary withManagedObjectContext:self.context];
...
}
after declaring handleOpenURL in the .h of course.
Thanks goes to Christian for putting in the effort for this.