I wondered if there are a way to be notified when a new application is installed in my device and trigger some treatment in my applications. Like PACKAGE_ADDED BroadcastReceiver in android
Thank's
Apple does not provide such information. Instead, you could add something like:
if([[NSUserDefaults standardUserDefaults] objectForKey:#"firstRun"] == nil)
{
//This is a first run
[[NSUserDefaults standardUserDefaults] setObject:#"NotFirstRun" forKey:#"firstRun"];
}
to applicationDidFinishLaunchingWithOptions:
update
If you instead want to detect the installation of another app the approach is different:
You can't detect when an app is installed, but for SOME apps you can detect if they are installed.
Doing your own app launch (or perhaps using a backgroundfetch process) you can see if an app is installed IF the app responds to a URL Scheme AND you know that scheme.
Take a look at
([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]])
If this methode returns YES for a given URL Scheme you know that app is installed. Here is a partial list of URL Schemes for some common apps or search http://handleopenurl.com/. You can of course also make your own URL Scheme if you want to detect your own app.
No. Apple doesn't give you this data.
What you can do, however, is maintain an user defaults data and manipulate in applicationDidFinishLaunchingWithOptions: delegate.
I've used a library called 'GBVersionTracking' for detect when is his first launch.
Importing this library you can send messages to the class 'GBVersionTracking' like:
[GBVersionTracking isFirstLaunchEver];
[GBVersionTracking isFirstLaunchForVersion];
[GBVersionTracking isFirstLaunchForBuild];
https://github.com/lmirosevic/GBVersionTracking
Related
After looking at a bunch of SO posts about detecting if this is a fresh install or not, I'm assuming what I want to do is impossible, but I'm going to ask just in case there's a trick I'm unsure of.
I am building an SDK to be integrated into apps, and I want to be able to tell when the SDK gets initialized for the very first time if it's from a brand new install, or from an app update which included our SDK.
I could have the integrator to call something like [MySDK initializeIsNewInstall:YES/NO] and force them to figure out which it is (using NSDefaults or whatever), but I'd rather be able to figure it out automatically somehow.
If anyone has any ideas, that would be great.
I would like to suggest pretty good trick by using [NSUserDefaults standardUserDefaults]
do it like this,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([[NSUserDefaults standardUserDefaults] boolForKey:#"isApplicationUpdated"]){
// application was updated//
// make another userDefaults to store version number and confirm if it is updated here.
}
else{
[[NSUserDefaults standardUserDefaults] setBookForKey:#"isApplicationUpdated"]
// as for the first time application would not find this key and you can use it after you have updated the app do stuff here
}
Afaik the only way to detect whether your app was updated or freshly installed in your case is to check your persistence for something that should be there from a previous version. For future checks you can add your own flag to your persistence.
I've got the following problem:
I created a Today Extension, which contains an UISwitch. The IBAction of this switch in Today Extension should store the on-state using the NSUserDefaults with the initWithSuite like this:
- (IBAction)switchStateChanged:(id)sender {
BOOL isOn = self.preferenceSwitch.isOn;
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.x.TodayExtensionSharingDefaults"];
[sharedDefaults setBool: isOn forKey: #"SwitchState"];
[sharedDefaults synchronize];
}
Now in my Containing App, I know that i can access the switch state using this:
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.x.TodayExtensionSharingDefaults"];
BOOL value = [defaults boolForKey:#"SwitchState"];
I'm looking for a solution that gives me a callback in my main containing app, when the value of the switch is changed.
In this solution, i have to set a NSTimer that refresh the user-defaults every 200ms for example.
Is there any solution by adding an Observer to the sharedDefaults?
I think this will work for your use case:
When you leave your app and open up Notification Center,
- (void)applicationWillResignActive:(UIApplication *)application
is called in your AppDelegate. When you come back from the widget,
- (void)applicationDidBecomeActive:(UIApplication *)application
is called in your AppDelegate. So just check your value then and fire off a internal notification to your controller. You shouldn't have any need for a timer.
Observing the change in your app is not a good solution, even if you could make it work, because you can't be certain that your app is even running when the switch value changes. It's also not how today extensions are intended to work.
If your app needs to know the state of this switch the next time it runs (recognizing that it might not be running when the switch is tapped), you're already doing the right thing.
If you need to immediately notify your app that the switch value has changed (again, recognizing that your app might not be running and that doing this might launch your app), you should create a custom URL scheme for your app and then open the URL from the extension. This would be something like:
In the app, declare a custom URL scheme in the "URL types" section of the app's "Info" settings.
Also in the app, add code to the app delegate to receive requests to open URLs.
In the app extension, use [NSExtensionContext openURL:completionHandler:] to open the URL. This will launch your app and pass the provided URL.
If the URL scheme is something like mygreatapp, the app extension would open a URL like mygreatapp:. You can add detail to the URL if needed, or the app can just use user defaults to look up the saved value.
I am displaying on the touch of a button inside my app, an app on the appstore. The app pops up in a SKStoreProductViewController with the content of the app store. Now, is there any method to detect if the user has pressed install on the shown app, or even better, be alerted if the user has pressed intall and the app has finished installing? Since the user in my app in this way is capable of buying the fill version, I want to quit the trial when the download is over.
I dont think you can detect if user has pressed install or an app is installed when using SKStoreProductViewController [docs]. Only API iOS exposes is loadProductWithParameters:completionBlock:.
But if you want to check if your app has installed or not there are other ways -
1) Using custom URL scheme. Define a custom URL scheme for your app and then check using UIApplication -canOpenURL: That will tell you only that an application able to open that url scheme is available, not necessarily which application that is. There's no publicly available mechanism to inspect what other apps a user has installed on their device. Custom URL scheme check can be done something like this -
BOOL fullApp = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:NSString* urlString = [NSString stringWithFormat:#"yourFULLAppURL://"]]];
if(!fullApp)
{
NSLog(#"INVALID URL"); //Or alert or anything you want to do here
}
2) If you control both apps you might also use a shared keychain or pasteboard to communicate between them in more detail.
I am working on a way to update an enterprise app OTA. I am opening a url to a copy of my app from my own server inside the app when I detect a new version is available. This works well except I want to give the user the option of not updating the app if they don't want to. What I would like to know is if there is any sort of notification that is sent to the ios app if the user presses cancel in the dialog that pops up when the url is opened. In other words I want a way for the app to continue ONLY if the user cancels the update request.
Here is the code I am executing to update the app.
NSURL *url = [NSURL URLWithString:#"itms-services://?action=download-manifest&url=http://www.mywebsite.com/myapp.plist"];
if (![[UIApplication sharedApplication] openURL:url]) {
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
I wasn't able to find any information what-so-ever about the itms protocol in the apple developer docs. I was able to achieve the effect I wanted by presenting a custom UIAlertView asking the user if they wanted to update before opening the url, but this has the unfortunate side-effect of prompting the user twice if they want to update, and still doesn't really handle the case where they cancel the update after the first prompt.
Any help on the matter would be appreciated.
How programmatically restart an iPhone app in iOS?
I find this way http://writeitstudios.com/david/?p=54
But may be something simple.
The only way I know to do this is not ideal, but it works.
First, your app has to opt out of background execution (multitasking) The app has to quit when exited, not run as a background task. This is done with the plist key UIApplicationExitsOnSuspend.
Second, your app needs to register a custom URL scheme that can be used to launch the app.
Third, you need a web page hosted somewhere that when loaded will redirect to your app's custom URL scheme.
Forth, the user needs an active Internet connection.
To exit and restart, call UIApplication openURL on your hosted redirecting web page. Your app will exit and safari will launch and load your page. The page will redirect Safari to your custom URL scheme, prompting Safari to internally call openURL, causing iOS to launch your app.
my post that you linked to is referring to a Cocoa Application, not the iOS. On the iOS, you can quit an application (but Apple doesn't like this) by using exit(0); but I don't recommend that. You cannot restart iPhone apps though.
Unless you're developing for jailbroken devices, Apple won't even allow you to programatically terminate your app. So restarting the device is out of the question.
Your AppDelegate instance has a method
(void)applicationDidBecomeActive:(UIApplication *)application
{
}
In here, you can put logic to figure out if the app should restart, or continue doing whatever it was doing. For example you can have a BOOL variable appMustRestart that is false at first but gets triggered as true whenever something happens in your app that you'd like the next time to be a fresh relaunch.
if (appMustRestart)
{
[self resetVars]; // call a method that resets all your vars to initial settings
// INSERT CODE HERE TO TRANSFER FOCUS TO INITIAL VIEWCONTROLLER
}