I am playing with idandersen's scifihifi-iphone code for keychain and came across the following behavior - I set the password using, say
[SFHFKeychainUtils storeUsername:#"User" andPassword:#"123"
forServiceName:#"TestService" updateExisting:YES error:&error];
Then delete test application from device and install it again - the previously set password appears to remain in keychain...
Is it the expected behavior? And is there a way to make sure that password I set will be deleted with the application?
Yes, this is the expected and correct behavior.
Some keychain items may be shared with other apps you control (that share the same keychain item access group).
You should just leave the info alone when your app is removed. You have no callback or method of removing the keychain items on deletion of your app.
Edit:
They finally reverted the behavior described in my answers, so until everybody move away from that range of versions, this should not happen anymore.
Unfortunately, this is not the case anymore. It has been changed since iOS 10.3.
This is an intentional change in iOS 10.3 to protect user privacy. Information that can identify a user should not be left on the device after the app that created it has been removed.
It has never been a part of the API contract that keychain items
created by an app would survive when the app is removed. This has
always been an implementation detail.
See the reference here.
Related
I'm developing now an app for Apple TV. It is a client-server app. On registration, users get a free trial period. My goal is to avoid situations when user will just register new account or reinstall the app and get the trial period again. I need to identify if trial was already activated for each concrete device. So I would like to know if there is a legal or semi-legal way to identify each device? I will appreciate any ideas!
You can store some value in the Keychain (read more about it
here) and check if this value was previously stored in the Keychain. If so, it means that user installed your application before.
You can use identifierForVendor (documentation) but that changes once the app is uninstalled.
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.
Perhaps you could couple that with a user's email address to prevent creating new accounts. Not foolproof, but certainly makes it more difficult for the user to get around it. They would need to uninstall the app and use a different email address to circumvent you.
I decided to import this project on my app i found on github lockscreen. Essentially it works just like the iOS pincode lockscreen but in this case it protects the app from being used a random snoopy person. The lockscreen works my issue is if in case I had set a passcode lock pin and delete the app off my iPhone and reinstall it the lockscreen still askes for to enter a pincode. I believe this is being caused form a cache storing the set pin codes for the app. Is the a way to delete the cache at relaunch or in the event of deleting the app ? I suppose this would be implemented in the delegate? How could you do this
Well yes and no. The passkey is stored in the keychain, from which you will need to remove it.
The way to do that is to check on startup that it is a new install of the app and clear the current value of the passkey form the keychain.
Since there is not code executed on the removal of you app you can't really do it after or when the app is removed.
I am researching UDID alternatives, and OpenUDID seems interesting.
I have done some testing and if I remove the app, and re-install again, the value of OpenUDID remain the same, I am just wondering how they do that and is the value always guaranteed to persist if I don't hard reset the phone.
They do NOT use the keychain, they use the UIPasteBoard, which is a shared OS construct that persists across device restarts. From the doc:
"system pasteboards are persistent across device restarts, application uninstalls, and restores."
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPasteboard_Class/Reference.html
Giving a quick glance at the naming conventions they use, I'd say they are almost certainly using the iOS keychain. This is the same as the OS X keychain, except it doesn't allow end users direct access the way Mac OS X does. Even if the app is uninstalled, this information will not be removed. It is stored in a controlled environment to prevent jailbreakers from getting it.
I would suggest BPXUUIDHandler.
I sent an app using it 5-6 days ago and the app is approved yesterday(by Apple, which means it passed 1 May, 2013 - lose your udid's) , it persists unless the device is restored. I used it in 5 or 6 apps of mine and never had an issue with it.
I've configured our app for iCloud usage with the appropriate entitlements, under a provisioning profile that is set up for iCloud, and a developer profile that's associated with this provisioning profile.
The application identifier matches what's specified in the provisioning profile (com.ourcompany.ourproduct). I don't get any errors when building the app.
iCloud is enabled on my phone, and is working (as evidenced by my calendar, contacts, and bookmarks being updated).
And yet this fails (localID is a valid NSString):
NSUbiquitousKeyValueStore* iCloudStore = [NSUbiquitousKeyValueStore
defaultStore];
[iCloudStore setString:localID forKey:#"ourKey"];
If I call synchronize after this, it returns NO. If I allow plenty of
time for the update to occur, subsequent attempts to retrieve the data
still fail.
Any idea what the culprit could be here?
Thanks!
In the simulator, NSUbiquitousKeyValueStore will just store values on disk and won't even try to synchronize anything.
On the device, synchronize will generally fail because your kvstore-identifier entitlement is incorrectly set but you should then see an error log in your Console.
Are you running it in the simulator? iCloud sync doesn't appear to work in the simulator, only on a device. Beyond that, your code looks good. I would expect it to work.
I also noticed that I was able to store and retrieve keys even before I set up my entitlements. I'm assuming the entitlements just allow you to link a key-value store to your App ID so that multiple devices or multiple apps from your company can share a store.
Knowing this, you could try completely removing references to iCloud in your entitlements and see if that works. Just for testing purposes.
With APNS, when a device registers, how long is the token it registers with good for? The entire time the app is installed? I seem to recall a note in the documentation saying it was only good until sync/reset, but looking at the docs again I can't find that note (and it hasn't held true in my (admittedly non-extensive) testing). Can anyone confirm how long each token is valid for?
In addition to changing when a device is wiped clean, a token for a app/device combo will also change when being debugged on a device with Xcode vs. when that same app is run from a released (app store) version of the app.
I ran into issues recently when I was storing multiple device tokens for my own phone. I had two tokens in our database for one phone. One was assigned to me when I was developing with Xcode and the other was assigned from the released version of the app.
The problem was the debug token only worked on the sandbox servers and the release token only worked on the production servers. When I was testing, I was sending alerts to both tokens and Apple would drop my SSL connection because one of them was invalid.
That being said, I believe Apple reserves the right to change them whenever they want, which is why it's necessary to request the token on every application launch.
I hope that helps.
Looks like it only changes when a device is wiped. Found this in the documentation for application:didRegisterForRemoteNotificationsWithDeviceToken:
Note that the device token is
different from the uniqueIdentifier
property of UIDevice because, for
security and privacy reasons, it must
change when the device is wiped.