I would like to know if a user has previously had the app installed on the same device. Is there some sort of unique id I can check?
You can use shared Keychain to store your AppId and other sensitive informations and fetch on app launch. Deleting the app will not remove/clear data from keychain. You will save and clear data programmatically. Also Apps from same family(developed by same team) only can read data from a shared keychain and data is kept in encrypted form so this is fully secured. You can follow bellow link.
http://evgenii.com/blog/sharing-keychain-in-ios/
User can change identifierForAdvertising any time in Settings, identifierForVendor changes after reinstall app, if no more apps on device from this vendor.
Here is alternative and the best solution for get or persistent, cross-install Device Identifier:
description: https://blog.onliquid.com/persistent-device-unique-identifier-ios-keychain/
code: https://gist.github.com/miguelcma/e8f291e54b025815ca46
You can check that the app is currently available in the iPhone or not from the below code. Here instead of the string "yourappname://", you have to specify the url scheme of that app. You can find the tutorial of the URL Scheme from this link.
Swift code
let appInstalled = UIApplication.shared.canOpenURL(URL(string: "yourappname://"))
if(appInstalled) {
print("It is installed")
}
else
{
print("It is not installed")
}
Objective-C code
BOOL isInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"yourappname://"]];
if(isInstalled){
NSLog#("It is installed");
}
else{
NSLog#("It is not installed");
}
Related
I am new to Xamarin iOS and mobile dev in general.
I have a application which requires location services, on my view controller I have a button which takes the user to location settings for the app, however, if the main device location is off the user will not be able to do anything with the app level location setting.
I am using this code on my button click event to take the user to the settings page.
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
NSString settingsString = UIApplication.OpenSettingsUrlString;
NSUrl url = new NSUrl(settingsString);
UIApplication.SharedApplication.OpenUrl(url);
}
I would like to know if there is a way to check if device level Location services are off and take the user to that settings page instead of app-level location settings and vice versa.
Also how to take users to Location settings screen if device level location services is disabled. I tried a few combinations but I am unsure what the NSUrl will be.
To check the Device level location permission:
bool deviceLevel = CLLocationManager.LocationServicesEnabled;
Document here: determining_the_availability_of_location_services
To check the app level location permission:
public void CheckAuthorization(CLLocationManager manager, CLAuthorizationStatus status)
{
switch (status)
{
case CLAuthorizationStatus.Authorized | CLAuthorizationStatus.AuthorizedAlways | CLAuthorizationStatus.AuthorizedWhenInUse:
Console.WriteLine("Access");
break;
case CLAuthorizationStatus.Denied | CLAuthorizationStatus.NotDetermined | CLAuthorizationStatus.Restricted:
Console.WriteLine("No Access");
break;
default:
Console.WriteLine("No Access");
break;
}
}
Document here: clauthorizationstatus
Update:
Have a look at answers in there two threads: how-to-programmatically-open-settings-privacy-location-services-in-ios-11 and how-to-open-location-services-screen-from-setting-screen
There says
Avoid use of "prefs:root" or "App-Prefs:root" in you app, otherwise
App will be rejected from App Store. Just open Setting page.
You can not open the device location permission directly, it is not allow through App Store rules.
Just use UIApplication.OpenSettingsUrlString; to open the setting page.
Welcome to mobile and Xamarin! Yes there are several Nuget Packages you can add that will help you do this. One that's gaining popularity is Xamarin Essentials.
As they show in the documentation, just try to get the location, it will handle permissions by itself, and if you face PermissionException, then you can open the settings as you are! Happy Coding
You can check if the user has disabled the Location services at the settings level then check the app level:
if(!CLLocationManager.LocationServicesEnabled)
{
Console.WriteLine("Location Services are off globally go to settings");
// This may get your app rejected using the strings below
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
UIApplication.SharedApplication.OpenUrl(new NSUrl("App-Prefs:root=General"));
}
else
{
UIApplication.SharedApplication.OpenUrl(new NSUrl("prefs:root=General"));
}
}
else if (CLLocationManager.Status == CLAuthorizationStatus.Denied ||
CLLocationManager.Status == CLAuthorizationStatus.NotDetermined ||
CLLocationManager.Status == CLAuthorizationStatus.Restricted)
{
Console.WriteLine("Location Services are off just for your app, got to app settings");
UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));
}
In terms of opening to the system settings or the app settings, UIApplication.OpenSettingsUrlString will go to the app settings as per the docs:
UIApplicationOpenSettingsURLString
Used to create a URL that you can pass to the openURL: method. When you open the URL built from this string, the system launches the Settings app and displays the app’s custom settings, if it has any.
You can use the string:
prefs:root=General
or for iOS 10 and above
App-Prefs:root=General
But Apple may reject your app, tbh I think it's not worth trying to go to the settings just for this reason but up to you.
I want to check whether or not my application was previously installed on a particular device. Is there any programmatic way to do so?
You can use keychain. but when user reset his/her phone this value will be lost .
I think there is no option is available to such case except you have to use iAd in your app. apple provide unique id for that that will remain constant after reinstall application.
OPTION #1:
You can use NSUserDefaults or save the flag to keychain, in order to not lose it after app uninstall, and check in application:didFinishLaunchingWithOptions: method:
BOOL installFlag = get it from user defaults or keychain;
if (installFlag)
{
//App was installed
}
else
{
//This is the first install ever
installFlag = YES;
//Here save the YES value to user defaults or keychain
}
If you will save the flag to keychain, then use a Keychain Wrapper, like this
one.
The weak part of this option is that even if keeping the flag in keychain, the value could be lost, after reseting device settings, that's why I would prefer the following option:
OPTION #2:
Keep the flag remotely on a server database, as a key you can use device identifier:
NSString *uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
And you will have to check, if there is a record in your database with current device identifier, then app was already installed, if no then add the flag and the identifier to the database. (But you will need internet connection every time).
You can use keychain to keep log of your app previously installed or not.
I need to know if user has certain apps on his iphone device
I have this code
BOOL isInstalled = [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:#"com.app.identifier"];
if (isInstalled) {
// app is installed }
else {
// app is not installed
}
which in theory does the job
the question is in practice, does it pass the app store?
can i use the "LSApplicationWorkspace" class ?
No.
All applications referencing private APIs and even undocumented APIs are not allowed.
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
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.