Is there a way for the developer of an App Store application to tie a sale to an individual user/device ID/Apple account? In other words, a method for the developer to double-check that a specific user has legally purchased the software?
I haven't been able to find a reliable answer to this yet. I'm not looking for specific code examples, just some sort of idea as to how possible (or difficult) this is.
My intent isn't to penalize piracy; it's to be able to provide additional benefits to paid customers. As such, I'm not looking for a way to identify a cracked or pirated version, which I gather has already been solved.
Thanks in advance for any help you can provide!
None of the answers were all the way there, so I'll summarize.
First, as per Tim's answer, Apple does not give you any information to identify customers of a standard app purchase, or to identify one specific sale from another.
However, using In-App purchases provides you with a method to identify a valid purchaser, directly from Apple. The information you receive in this manner is uniquely identifiable; it doesn't give you a user's device ID and/or Apple Store account, but it can be used to verify a specific transaction.
Apple's documentation on verifying store receipts.
You can roll your own system to do this. You're not permitted to look into Apple's information elsewhere on the phone, but you can let your users create an ID in your system, through your application's interface. Gather the information voluntarily from your customer at the time you have them create their Profile on your system. You can get the Device ID, but you may want to collect something like an email address, too, so that you can continue to provide them with consistent service, as they upgrade to a new iPhone, or add an iPad to their fleet of Cocoa Touch devices.
Be sure to use an encrypted http connection when you're talking to your server, so that you don't accidentally expose your customer's information.
To quote "Dr. Touch"...
AntiCrack contains proven technology
to mitigate the risk of your apps
getting pirated by automatic cracking
tools
You do not have access to any purchaser information from the Apple store. Apple considers these customers THEIR customers, not YOUR customers and so will not make any customer identification information available to you...
-t
Related
I would like to know if it is possible, and if it's ok with apple if my app will use the iPhone's GUID with my server, as I don't want to nag my users for User/Passwords ...
Thanks !
Apple is crazy about privacy and UDID still allows to differentiate devices etc so I suggest to calculate some hash for example md5 and only afterward to pass it to the server. Such approach will guaranty privacy to your users even if your DB will be compromised.
Apple generally allows this and a lot of analytics frameworks use the device ID for tracking purposes.
You should however consider whether your users' data contains any personal information. If this is the case, I would strongly recommend against using device IDs for identification as they might not be really secret, e.g. because other developers need users' device IDs for beta testing etc. Also, other developers transmit device IDs to their servers and could use those to get at personal information from your users.
See this article for a concrete example of how device IDs could be abused.
I'll soon have to implement the StoreKit functionality and I was wondering...
is there a way to also offer a product for free to a user once, like as a gift for using the app for the first time ?
In my special scenario I'll offer several products in my educational app, which the user will need to buy time by time, if he is interested in continuing to learn with the app.
But the first product I want the user to have for free and it should be his choice which one he takes. So generally all products should have a price, but the first download shall be free.
And I want this to get logged on my server so I can reidentify him, so (A) he can't delete the app, reinstall and download yet another free product and (B) so he will also get the products on any other of his devices.
I'm also open to workarounds, like maybe get something similar to the apple id or so, to be able to store it on the server. I know that I could also use the [[UIDevice currentDevice] uniqueIdentifier], but I want the user to have this first free product on all his devices, and ONLY ONE.
Is there a way to get (A) and (B)?
Apple's In-App Purchase infrastructure (and by extension, StoreKit) does not support free content.
But there's nothing stopping you from providing free content via your own mechanisms, as you surmise. You would have to do all the tracking yourself in terms of remembering device IDs on a server somewhere, and noting that device != user, so would miss some edge cases.
You don't get access to (iTunes) user data at all, so you probably can't guarantee the "only once" across multiple devices, unless your app has an associated backend service account that is already unique per user.
(Before building infrastructure for this, you should double-check the developer agreement/contracts on this stuff. You're not circumventing Apple's revenue stream here, which is good, but what you're talking about may be unusual enough to raise a flag with them in terms of experience consistency if nothing else.)
For example, if upon launching my app I wanted to see who the current caller was or what the latest SMS message was from "Phone" or "Messages", are there classes available that can access information at this level?
This may be a system security/stability/scoping issue that Apple wants to avoid, but it's worth a try.
You're assumptions are correct, this is not currently allowed, nor do I think it ever will be.
I believe their reasoning for this is so developers cannot access personal information like phone numbers and addresses and exploit them.
You can send mail and SMS messages from with the app, and you can see the current call state.
Your hunch is right, that it's a system security issue. Apple does not give access to such information, since it's definitely a breach of privacy. Sorry.
Is it possible to provide a service in which one free trial is given to each device without the possibility of an individual being able to get multiple free trials on a single device. If its impossible, do you know of a way of making it difficult to obtain multiple free trials.
You can generate the license key based on the device's unique ID, the request date, and your own private key to create a license that is only valid up to certain date.
You application will verify that the license key is valid by decoding the license key with your public key, and comparing its expiration date and device ID. People can't forge a bogus request, since the license key is only valid for the prescribed date and a given device ID.
(hint: read about public-key cryptography)
However, it's not totally foolproof. A really determined attacker can root his device, and install a custom firmware which allows him to control identifier returned by "getDeviceId()". This isn't something that most people would be willing to do, most people would rather find an alternative free app or just buy the app rather than going through that route. Against crackers with that sort of determination and skills, there is not much you can do about.
Alternative avenue of attack would be to replace the public key you ship with the application with the attacker's private/public key combination, and he can potentially write a key generator that can generate license key for the forged application. You can make this attack difficult by self-verification of your own executable.
However, no security scheme is foolproof, java/android application can be reverse engineered and a determined hacker can forge your application and disable its license checks. The only foolproof way to prevent unauthorized usage of an application is to not distribute the application at all.
I imagine you could get 99% of the effect of a more complex scheme with a brain-dead-simple one: just store a file somewhere on the device that indicates that the trial has expired. Granted, tech-savvy users would be able to find and remove the file, but the vast majority won't bother - the device is an inscrutable slab of magic to them, meddling with the internal files might displease the tiny gnomes peddling furiously behind the screen.
You can make things more challenging by hiding the lock file, changing the name and location based on the device id - that way it's a lot more difficult for someone to share instructions on how to evade your trial scheme.
As the other answers have noted: no system is foolproof, there is always someone out there who is cleverer than you and who will relish cracking your scheme. The trick is to not waste your time giving this guy a mental workout and instead cater for the majority.
Sure, but you'll need to be set up to store device identifiers on your own server. On an iphone, you can obtain the UDID using
UIDevice *device = [UIDevice currentDevice];
NSString *uniqueIdentifier = [device uniqueIdentifier];
You might make a database call and acompare uniqueIdentifier to your stored list, ensuring that only one trial can be activated per device.
In android, getDeviceID() gives you a unique device identifier. check the documentation for more info on this.
If I am not missing something, my solution would be straightforward. I will make the expire the service provided by the app, not the app itself. This can be done by using some token mechanism like oAuth. (with an expiring token with a considerable lifetime, in this case your trial period). While the client registration process, I will create the request token as a function of android device id and the requested time. Checkout oAuth, it could be a hassle, but almost all major service providers use it.
How about storing the MAC address of wifi adapter? Possibly on you server and you app will query the server if that MAC is already registered.
WITH USER'S PERMISSION, on the first run of app, query the server if current device's MAC address is already registered? If not, store the MAC address on your server. If already registered, ask user to purchase the app in order to continue using.
This method can be supplemented by some cryptographic algorithms as suggested by Lie Ryan to provide additional security and locks and/or trial period.
I don't know much about iPhone but I believe that every iPhone has wifi adapter and every wifi adapter has unique MAC address. Also check the legal side of this solution as storing the MAC may raise privacy issues/concerns. So, before using this, check laws applicable.
I would like to implement a application which backs up all the internal data like SMS, MMS, videos, audios, documents, call history stored in iPhone. But this seems to be not possible with API docs that the apple has released so far ... I have gone through the PDF of Enterprise distribution program and some of the links related to Enterprise Distribution Program, specifies about the Remote wipe and accessing of internal data like Calendar, SMS, MMS etc .... But they didn't mention how to do it programmatically.
Does Apple provide any special privileges like extra API support to access the internal data in their Enterprise Distribution Program?.
Is there any difference between Enterprise Distribution Program and Standard Distribution Program in the development point of view?
And since in-house distribution does not require Apple approval, shall we use some other method which are not officially mentioned in apple docs, to access the internal stored data ..
If so can anyone point out the way to do it?
Any help would be greatly appreciated
awaiting for your response
Best regards,
Mohammed Sadiq ....
You will not get any "bonus api", as there is no api, there's just public one, and private calls. Still, as you will distribute the app on in-house basis, you can use sqlite to get access to sms, calendar, phonebook data. I can't say for sure about other fields, as I don't know the exact permissions of the latest sandbox profile. You definitely can get access to everything on jailbroken device, but that might be not the best solution for you.
Standard and Enterprise are different in that Apple doesn't regulate the apps, as you said, I don't think there are any differences in development (except for what The company needs like internal server access) but there is the difference in distribution. You can't officially get that data programmatically but using undocumented calls sounds like it could work.