I'm trying to check the original app version that the user installed so they can have unlocked premium features without paying twice.
In StoreKit for iOS 16 there's an "originalAppVersion" property on a transaction:
https://developer.apple.com/documentation/storekit/apptransaction/3954447-originalappversion?changes=_8_2
Unfortunately this, and the "appVersion" property in development both return "1".
I was expecting a string of the form "1.0.5".
Do I need to do something different?
Related
Does anyone know why are users with older app version which doesn't have new experiment in config counted as part of experiment? This is scenario:
I have app version 1 with experiment A with activation event for new users new_install
Then I create app version 2 and new experiment B with same activation event for new users new_install . I start experiment on firebase console.
Now I am waiting for app to be approved by apple appstore or starting rollout on android. Even before any user gets app version 2 I already see many users showing in experiment B on firebase console.
I would expect that users with app version 1 will be not part of experiment because remote config doesn't have default value for experiment B in app version 1 but it seems that because users are still installing app version 1 and new_install event is fired, they are counted as part of experiment B event when it's not in app version 1.
Is it feature? Bug? I am supposed to create custom activation event for every experiment?
That's actually easy to prevent - and good practice for A/B testing in general - just target users with at least given app version. Usually it will be version since you have remote config properly set up.
I would not rely on Firebase including or excluding users if they don't have remote config parameter. Today it might work differently than how it's going to work in a month. If there is no guarantee, just make sure you are targeting users who are properly set up.
I'm automating test cases to run in several devices in parallel. I'm using Appium for this and this works fine. My issue is that I have some test cases that need the device to be logged into specific Apple Store accounts. Also, it is possible that the device might already be logged into another account and I don't have the option to logout manually. My test cases to log into an account if the device has no account attached to it already run well (inside my app I try to do an action that requires an Apple ID, the alert requiring login appears and I already automated the login process). The issue is when the device is already logged into another account.
My two options are:
Force the device to log out from Apple Store
Create a device backup without being logged and restore this backup before my test
I wasn't able to find a way to handle the first option. The second one works using idevicebackup2 (a lib from libimobiledevice). The issue here is that after restoring the device data, the setup wizard appear and there is no way to get rid of it automatically. I tried using cfgutils to remove the wizard steps, but even after removing all steps, the wizard appears just waiting for a confirmation after restoring.
I would like to know if there is a way to go for the first option, or a way to skip the setup wizard in the second option, or maybe a way to restore the backup partially (just clearing the Apple ID data) in order to avoid rebooting the device and getting stuck with the wizard again. Thanks in advance.
One option available now with Xcode 9 is the new multi-app testing. You can now call any app on the system based on it's bundle identifier XCUIApplication(bundleIdentifier: "com.MEGACORP.xyz") during a XCUI test. They cover the new API and examples in WWDC session 409 - What's New in Testing - it's worth watching the whole thing.
I've written some tests using the new API to switch out of the app under test and open System Settings to reset the app state during the test teardown. There's a list of all the system bundle ids in this question.
Your test would start with something like:
let store = XCUIApplication(bundleIdentifier: "com.apple.AppStore")
store.launch()
I want to know who the user is without them actually logging in. There are bunch of methods on the internet and the one I am currently using is:
static let DeviceId = UIDevice.currentDevice().identifierForVendor.UUIDString
The problem is this resets when the user deletes and reinstalls my app. Also somehow this value changes in about 1-5% of the users without them actually deleting the app. It happens after they upgraded to a new iOS version. Possibly happens when they change appstore country too.
I want the user id to be unique no matter whatever the user does. Kind of like how Whisper app works.
What is the best way to do this? Advertising identifier looks really good on paper, but does apple allow using that just for user login info?
Should I use keychain? icloud? Is there some other value I can use?
Here are some sources I read about this topc:
http://tinymission.com/post/ios-identifierforvendor-frequently-changing
http://possiblemobile.com/2013/04/unique-identifiers/
How to preserve identifierForVendor in ios after uninstalling ios app on device?
I read a few threads and it seems like the UDID is deprecated. I also checked out CFUUIDCreate() but that's not really what I'm looking for.
I'm planning to do give aways in my app, so the only information I need from the user is the email address and a unique identifier of the device. I don't want the user to be able to simply reinstall the app and re-register for the give away. The easiest way would be to send some kind of device identifier together with the email address.
Any suggestions?
EDIT: Can I use the MAC address for this purpose? Any other ideas?
EDIT2: Nevermind, that's deprecated aswell...
EDIT3: I think I found something: How to generate unique identifier which should work in all iOS versions?
EDIT4: I'm using the solution in the link above, it works great!
Apple no longer allowes access to UDID from public APIs.
Perhaps you can use a web service to tell the device by it's IP, etc. Although there may be a way to mislead it, it will be better than using nothing.
Another solution would be using iCloud, only a few users would actually make the effort to make a new account.
Whatever you do, remember to make sure you don't break Apple's AppStore guidelines:
https://developer.apple.com/appstore/resources/approval/guidelines.html
(see "20. Contests, sweepstakes, lotteries, raffles, and gambling")
See a list of possible identifications below. Only the CFUUID provides you an unique identifier, but when you reinstall the app the ID is regenerated.
You may save the mail address of the user who received a giveaway in a separate online db.
UDID
unique and permanent device identification
(deprecated)
CFUUID / NSUUID
Random-ID, which is not bound to the device
is for each installed app different
only persistent till you delete the app
Advertising Identifier
for all apps identically
can be changed by the user
can be globally turned off
Identifier for Vendor (IDFV)
identically for all apps of one developer
MAC adress
cannot be used
no identification of a device, because the API returns the same MAC address for all devices
this is my first ios app. am working on a version 1 that i'm planning on giving to few of my customers. customers will get it from app store. in future, if i have new version that i'd like to notify current users, is there anything that I have to put in version 1?
thanks.
Yes, you will need to put something in version 1 in order to do this if you want some kind of notification in the app itself. You can go about it a few different routes depending on how complex you want it to be:
You could add push notifications to your app, so that you can send a push notification to your users letting them know an upgrade is available. You would probably only want to do this if you used the push notifications for other purposes as well, as users probably wouldn't want to allow push notifications for an app to only inform them of app updates.
You could have your app check with your server upon app launch to see if there's an update available. You could simply have a file on your server that the app checks which can contain the version number of the most up to date app you have available. If the server reports a newer version than the version reported by the app, it can display a message, which could also be contained on your server to be configurable. This would be pretty simple to implement, and could possibly contain other configuration information for your app. You could also choose when to show the prompt, in case you don't want to bug users for some updates but do for others. This would be good to do if you might release an update that requires users upgrade in order to continue to have it work with a backend server.
You can also get your app to check directly with Apple to see if a newer version of the app is available on the app store. You should be able to find a resource that will instruct you how to do this. Going this route, as soon as an update is available it will start bugging users to upgrade, so you may not want to do this if you only want to push some updates on your users but not others.
You can do nothing. On iOS 7 by default app updates get automatically installed, and even if they have that disabled, the user can see what app updates are available in their app store app. This is what most apps do, aka they don't bug the user every time an update is available. And if somebody isn't updating their apps anyway, your prompt won't necessarily encourage them to do it either.
It's similar to the message appearing in Chrome when a new version is available - something like "Chrome has just got better".
Presuming that you have a server side counterpart, my approach would be the following:
store the latest version number of your app somewhere on the server (database, configuration file, etc)
implement an API at server side that, upon an app version provided as parameter, returns true if an update is available
in your app, read the current app version (see this SO answer)
call the remote API mentioned in (2), and act accordingly if the return value is true
Note however that appstore notifies the user when an update is available - but that doesn't happen in-app
Incrementing the app version is enough for App Store notification as explained in
iPhone app Update Vs new version