I'm writing an application which will be used in an enterprise, no outsiders.
This application should fetch data from API response and display it.
Each user has his own device, Ipad and should see only the data he is the owner of.
Problem i'm facing is identifying the device/user, so that API responds with only the information the user is supposed to see.
brief example of how it should work:
App is opened -> get unique id -> attach ID to API call -> receive appropiate response -> display data
As i imagine this ID should be static and not made upon installation of the app or generated.
I've tried getting UDID, Serial, MAC,- no luck, they're deprecated. Only managed to get .IdentifierForVendor, which is unique not in the way that i need.
So here is my question, are there any other options left?
Like fetching appleID name,email or should i make unique deployments for everyone separately?
Or a Log-in screen?
You could create a GUID for every App instance. However, apart from that you will have a hard time doing what you want.
These ways of identifying a device have been deprecated to ensure Advertisers and other malicious Apps cannot fingerprint a device easily.
If you don't want too much hassle authenticating everyone, you could apply a simpler scheme such as using a pin code, QR code, NFC tag or whatever you prefer.
However, if someone were to steal one of these enterprise devices and it would contain any secret information I would rather rely on something more secure as username and password, or even better something multi-factor.
Unique id's will have to be set by deploying the app from MDM. For example:
https://docs.jamf.com/9.9/casper-suite/administrator-guide/In-House_Apps.html
How should the application accept those variables, i dont know. Maybe it modifies .plist when deploying.
Solution i did was enforcing device name from MDM, so that users are unable to change it - and using that as the unique identifier.
Related
My project have a case: one account user can only log on to one device ( if user log on to app in device A, user can't log on to app in device B). My Idea is: when user login, I'll get the imei Iphone (like android) and send it with request login to server. But I can't get imei. I try with UUID, but UUID will change when re install app. Keychain does not solve the problem. Please help me.
You have to use Keychain to store Unique Id , this will not change even if user delete app
You can use any wrapper Source code to do this
here is an example
https://github.com/Joe0708/KeychainUUID
At the beginning I'd like to mention that I do not know any method that directly answers your question, especially that Apple does not allow you to read IMEI and other similar stuff due to privacy concerns. This has been answered here.
The workaround might be as follows
Take a look at the UIDevice class, especially at the identifierForVendorProperty which provides you (according to documentation ) with a device specific value.
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.
As far as i know some financial apps are secured this way to permit only one device to access the account. This however requires registering a device each time application is reinstalled.
Alternatively you can use UUID you generate within your app (first run) and then you assign it for the user online. It might take the form similar to two step verification process. Be aware however that with such restrictions user will have to be online all the time to use your app.
I'm trying to get the Device ID via Google Tag Manager but got an error on iOS. After a quick search it seems that Apple blocked this.
Moreover, it seems that using idfa is not recommended (can lead to troubles to validate the app) and sometimes lead to unexpected errors.
What are my options here ?
Get the device ID via code and somehow (I don't know hate btw) push it to the data layer to retrieve it later via GTM ?
Find another unique ID ?
What would you suggest ?
Apple has blocked developers of using any kind of unique device id, like uniqueIdentifier, mac address, etc...
As you noted using the IDFA for this might get you in trouble, you are only allowed to use this for advertisement purpose.
There is the identifierForVendor, this ID is shared between all app from one developers. This ID will not change wil the user has any app on his device from the same developer.
The last option is to create a unique ID yourself and store this in the keychain where only you app(s) can access it.
I all cases you will have to push the value into tag manager yourself.
Scenario:
I "control" two different apps, App A and App B, both which the user has installed
App A is running
App A needs to obtain a string that was set by App B when App B last ran.
After obtaining the string, App A will still be running
User should not receive any feedback this communication is happening. E.g. no "switching animations" between A or B, no pop-ups, etc.
Constraints:
Apps are released under different vendors
Apps are already in the app store; updated versions will have this communication ability.
It is acceptable for the data stored in App B to be accessible to other apps on the device.
It is not acceptable for the data stored in App B to be visible to general third parties (e.g. if an external server is used, there needs to be some sort of secured scheme)
The data read should be able to occur immediately upon App A being opened after install. For instance, I cannot require the user of App A to enter log in credentials for an external communication service.
Must work on non-jailbroken devices.
This is seeming rather difficult to pull off in iOS7. Help is appreciated.
Tricky work around. Not recommended, but it will get the job done if you can't afford servers.
On the first app create a contact in the user's contacts book. Give it a generic name like "000 - NameOfAppB Data - Don't Delete" (I start with "000" so it goes to the bottom of the users contact book so they never see it, I also add "don't delete" so if the user does somehow find it they don't delete it hahaha) (who looks at contact books anyways). In the contact info under notes add your NSData in string format.
Then when app A is opened search for that contact, read the data, then delete the contact.
Apple does allow you to create and delete users contacts without their permission. (At least in 2011 they did, this may have changed).
This might serve your purpose
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/Reference/reference.html
I am not sure of its limitations though, i have seen implementations where credentials have been shared between apps.
I have an app that is uniquely branded for each customer (think restaurants, etc.) I need to have the user be able to click on a link to my server that contains a unique code, stores that temporarily on the iOS device (cookie, etc.) and then directs them to the app store to download the app. Then when it is downloaded, the app grabs that cookie or temp. data on launch and brands the app for that customer. I know this is possible on Android, but is it on iOS?
Downloading the app first and then selecting the brand (or restaurant) is not feasible in this case, as the url wil be shared with other customers of the same business and we want to create a fluid experience, where they won't be able to "see behind the scenes" and choose a different branding.
Thanks
Edit
Thank you for all the replies. We've reevaluated and are considering having the url be opened on the device and grabbing the IP address or another unique id, and saving that along with the correct brand to a database. The app will then connect to the database on launch, and if the IP's match, will brand accordingly. We're looking for a more reliable identifier than IP, however. Now that UDID is deprecated, are there any other identifiers we can use?
I think the design you propose of a webserver link creating the code that needs to be read by the iOS app later is the issue. You should have a solution that is entirely app based. Perhaps you can have the same services on the website be available as one app which then sets up the code in pasteboard. The user then launches the actual app that looks at the pasteboard and skins itself accordingly.
That being said, data can be shared between apps from the same app seed ID by using UIPasteboard in addition to a few other ways.
I use the pasteboard to share info between apps quickly and easily using this class.
You can use identifierForVendor (UDID replacement) to identify individual devices. Are you planning on harvesting those identifiers prior to the end user "registering" the device at the final location? If not you'll never be able to determine which device belongs where.
What about having the end-user logging into your server as that restaurant? It can be a somewhat generic login per restaurant like "Wendys/Wendys5?" and "McDonalds/McDonalds7!" to determine their App Store URL. As long as the password is easy and non-programmatic to guess it would be unlikely they figure out how to register as a different restaurant. You could also do a simple restaurant selection screen coupled with a password specific to each chain but this would expose the user to which other restaurants are using the app. This way you won't have to continually add IPs if they expand locations and can revoke credentials if the login is compromised.
One question, though: Do all of your clients understand that they'll have to have an AppleID tied to each device? You can only shared a single AppleID across 20 devices.
Not exactly a programming question but here it goes:
How can a company who is distributing passbook passes via email or web prevent a pass from being installed on more than one device?
I can not find anything about this on Apple docs. The only I can think of is to check on the device registration webservice whether the combination of pass type and serial has a device already registered and delete it , but I am not aware of any command to delete the pass remotely.
Another option would be to check if it is already registered prior to generating the pass but this would only work for URL distribution, not for email.
Is there any way to delete a pass remotely via push notification + update? Any ideas on how to solve this issue?
Mail and Mobile Safari will present any pass they are given and the user can decide to add them to their Passbook. There is nothing the pass creator can do to prevent it except to be careful about how the .pkpass files get handed around.
If you really only want to deliver a specific pass to a specific device you might consider a companion app that uses a custom API to communicate with the the backend and request the pass for that device that way. Then you have much more control than distribution via email or url links.
Apple frowns on trying to delete a pass programmatically; only users are supposed to delete passes because they added them. You can, however, update a pass to make it clear that is not valid and should be deleted. For example you can remove the bar code, if any, and use a background image with a big red "INVALID" on it.
Just to extend #ohmi's answer:
You cannot prevent passes from being installed on more than one
device - e.g. if user enables iCloud for Passbook, the passes will get
synced automatically across devices.
Considering your links to pkpasses are public, you may want to consider
introducing one-time download links, but while it can fill your
needs just fine, users can be really disappointed if it's impossible to re-add
passes that they manually deleted. So I wouldn't recommend such solution.
You can make you pkpass links kind of private, so only GET request originating from your application and carrying a specific value for specific header field (e.g. auth_token), will receive a pkpass file, however this way you almost disable pass distribution via email or via sharing URLs to passes and make pass updating probably impossible.