Detect first time app download on iOS - ios

I already have a application on App Store and business team needs to detect the users who's downloading and using the app for the very first time.
Challenge is there's no login for the app and customers can purchase tickets. We need to give a promotion only for the customers who downloaded after some future specific date. (ex : customers who will download for first time after 1st January 2018)
Even if the customer is deleting the app and then re install from apple store, it should not be eligible for the offer.
we can do some code fix and update. But that code will not be affected until they update and launch.
Note: It should be first time download only (i.e. they have never had the iOS app on their phone)

As far as my knowledge, There is no way for us to know whether a user has reinstalled user or not until unless we do have our own custom logic like sending emailId or storing in Keychain.
In your case, you have not done any of these things for the app which is already live in the app store. you can not track the reinstalled users. Please find the below segregation of users.
1. Reinstalled Users: right now not possible to track these users.
2. Installed Users (v1.0) & New Users.(V1.1)
check this solution How to determine the date an app is installed or used for the first time? to get the timestamp of the document file.
a. If it is less then new app release, then it should be an older version.
b. If it is equal or greater than the new app release timestamp, then it is the new version.
write the keychain logic in the new version so that from now onwards you can use keychain to identify the users.

Use CFUUID to create UUID, then save it in the keychain. So whenever the app launches, if no UUID is found in keychain, it can be said that app is installed for the first time. If UUID is found in keychain, it can be said that app has been installed previously. Have a look at below links:
iOS UDID replacement
UDID equivalent
iOS unique user identifier

In our case, we were keeping some local sqlite database in the documents folder. So if the file doesn't exist at the time of launch we can assume its a fresh launch. Otherwise its an update.

Related

How to Test an iOS App as if First Time, Each Time?

Here’s my situation:  I have an iOS app in development.  To thoroughly test each new beta version, especially the content purchase process which happens after the initial app install, I need for my device (iPad) to forget it has already seen and purchased the content of the app before.  Once I purchase, though, each subsequent download automatically activates the previously purchased content, so I don't get to start fresh.
As a solution, I was going through the laborious process of creating a new iTunes account, doing a factory reset on my iPad, adding the new account as a new tester in the iTunes Connect Test Flight system, and testing that way.  It worked a few times.  What I just discovered, though, is that Apple only allows three different accounts to be registered on a single device over the course of a year, so that plan is no longer viable.
My question, then: How are developers testing apps that need to load as if for the first time in a device, after the app has already been perviously loaded and tested?
Stumped on this, appreciate any help.
Cayce
The app's data should be deleted by just deleting the app. If it is storing data elsewhere on the device then you can go to Settings-General-Reset-Erase All Content and Settings.
That should do it.

iOS Switching from paid to free app, how does one know who previously purchased the app?

I have a paid app that was released on iOS 4. It hasn't been updated and I'm now reworking it to work with iOS 10. Since in app purchasing was not a thing, I made a free (lite) and paid version of the app. I would like to update the paid version to iOS 10 and change it from paid to free with ads and an in app purchase to remove ads.
I tried researching various methods and I have not found a fool proof way or evidence that one will work in all cases. The two most prevelant methods I found:
Use an existing UserDefaults key value to determine if they opened the old app and then grant them no ads in the new version.
I don't think this method will work, as if the app was uninstalled or the user redownloads it after the update they would not have that value.
I believe iOS 7 offered receipt checking. Use receipt checking to determine if the user has paid for the app and check if the date is before the new version date.
I'm not sure if this would work either. I saw in the documentation to verify locally. Would everything I need exist if the app was an iOS 4 app originally? Would this work for users who had the app through a promo code? What if they don't have an internet connection at the time they open the app? I had trouble finding sample code for this option to test.
How would I go about doing this? Are any of the methods above the only way or are there others?
Out of all the resources I found on this subject, checking the receipt seems to be your only feasible choice. If you have an account where you purchased your app, you can run the new version of the app via Xcode with that account and see if the receipt validation gives you the expected information. Though installing the app via Xcode may alter the receipt that the account has, you may want to check on that.
NSUserDefaults option could work if you were setting any value to NSUserDefaults on the iOS 4 version.

Different UUID in swift 2.2

Before Swift 2.2 the UUID value was the same every time I opened the app, now changes at every opening
I use this code:
UIDevice.currentDevice().identifierForVendor!.UUIDString
How can I do now to identify the user?
Every time you delete the app, the UUID may change.
If you just close and open the app, it's should be the same.
But if you delete the app (or install it again via xcode), it might change.
There are a couple of answers that explain why the UUID is resetting. There's one that offers a potential work around, but I'd consider it far from ideal. But I want to highlight something important about the way UUID's work that serves as a great workaround that has absolutely zero impact on the production OR debug version of your code base or compiled binary.
The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them.
All you have to do to prevent this value from changing while developing App-A is to simply install App-B from the same vendor (yourself) and keep it installed during the life time of App-A's development. This is literally as simple as starting a blank new iOS project and install the blank slate to your test device (using the same developer account & such), and then never uninstall it again during development.
App-B keeps a constant UUID for the vendor (yourself) so no matter how many times you delete and reinstall App-A, it will always keep the same UUID.
This actually seems to be a bug IMO. Everytime I run my app in the simulator it generates a new Vendor ID. You can probably get round it by storing the ID into NSUserDefaults on the first bootup then retrieving / comparing the value from NSUserDefaults instead of getting it from identifierForVendor. This will save a static vendor id in defaults but in theory the vendor id will still be changing every boot up.
Kind Regards,
Krivvenz.
Update: I can confirm I have installed multiple apps on the same simulator too but the vendor ID is still changing on every boot.
Update 2: - I have logged this as a bug with Apple - 26195931.
The value of this property is the same for apps that come from the
same vendor running on the same device. A different value is returned
for apps on the same device that come from different vendors, and for
apps on different devices regardless of vendor.
The value in this property remains the same while the app (or another
app from the same vendor) is installed on the iOS device. The value
changes when the user deletes all of that vendor’s apps from the
device and subsequently reinstalls one or more of them. The value can
also change when installing test builds using Xcode or when installing
an app on a device using ad-hoc distribution. Therefore, if your app
stores the value of this property anywhere, you should gracefully
handle situations where the identifier changes.
Refer this link for more info.

iOS: why some app can restore the account info when reinstalled

Some apps, If you have ever used it on your iPhone once and then uninstalled it, the next time you install the app, the app can still retrieve your info that you filled out before you uninstalled it last time.
How does the app do this?
It's because they save account information on the keychain.
Data stored in the keychain persist even if you uninstall the application, they are only removed if you perform a full restore of the device, or you remove by yourself.
This is a complete different behavior respect to NSUserDefault that is removed within the application deletion.
Data in keychain can also be shared between applications (if you implement it in the correct way) that use a similar bundle identifiers.

I need to check the itunes store to see if a user has bought a subscription in the past version of my app

I'm rolling out a new version of an iPad app, and you could buy subscriptions on the old version. However, the new app has different subscriptions than the old one did, but I still need to know if they used to have a subscription, so I can apply it to the new app.
So, how can I check the iTunes store to see if they bought a certain product in the past when they load the app? From what I can tell it should be possible to do because it is the same app and connected to the same app ID in the iTunes store.
I'm trying to get some sample code to put in here but I have literally no idea where to even start.
You can use the SKPaymentQueue's -restoreCompletedTransactions to restore everything apart from non-recurring subscriptions. Your observer should get then receive every relevant transaction since the beginning of time, each with a state of SKPaymentTransactionStateRestored.
Apple requires you to support transaction restoration so hopefully your old version's code should have this built in somewhere, behind a 'restore' button or similar.

Resources