How can one app provide data to another without swiching apps? - ios

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.

Related

Firebase insecurity/public endpoints with iOS app

I've frequently heard that the main issue we need Firebase security rules is because an application contains all the configurations needed to connect to the database and thus users could do something like db.delete('*'), read/write whatever they want, etc. etc.
I can see how this is possible on a web app, as you could check out the requests being sent over the network and thus get the endpoint needed to connect to the database, but, on an iOS app, how would this be possible?
For instance, say I created some chat app with Firebase and released it to the App Store. When a user downloads it, how would he/she gain access to my database through an API other than the buttons etc I provide with them with? Is there something equivalent to the "Network" section in google chrome that shows all outgoing requests, and, from, this they could send a malicious request to my database? Would this require installing 3rd party software onto their device to see all outgoing/incoming requests and they could get the required endpoint/database connection info from there?
Thanks.
When a user downloads it, how would he/she gain access to my database through an API other than the buttons etc I provide with them with?
It's not hard to reverse engineer the contents of the IPA file to get both the configuration you provided, and also see what the code is that queries the database. The IPA file can be obtained pretty easily - there is not much protecting that, given the user effectively has full control over the device (e.g. jailbreak). Given that information, it's possible to simply invoke the public Firestore REST API to not just duplicate all the operations in the app, and but invent operations of their own.

Xamarin IOS identifying device

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.

Deferred Deep Linking in iOS

We're trying to implement deferred deep linking in one of our iOS applications to encourage users to invite their friends to use the app, and reward users based on how many installs occur from their referral link. Basically similar to TapStream's product.
Consider this example:
So, UserA shares their link, “ourappURL.com/refer?id=userA”, on any
network they want. UserB clicks that link, which will take them to
Safari and then bounce them to the App Store page where UserB
downloads the app.
When UserB opens the app, the app checks which referral ID they came
in on (if any). In this example, the referral ID would be “userA” as
that’s the ID that was in the referral link. The app then sends this to
our servers and we award UserA with a referral credit.
I'm trying to break this issue down into its core parts. I believe the first part is getting the web page for the user's referral link to save the referral ID to the device somewhere that the app can access it. But I'm not sure this is possible because of the sandboxed nature of iOS.
I know this is fundamentally possible because many ad providers offer the ability to track installations from an ad campaign (see Mobile App Tracking for example).
We have also attempted to do this ourselves and I will try to break down the different steps here.
Going back to your example, you are correct about "remembering" the device identification, and all relevant data "id=userA". You are also correct about "sandboxed nature of iOS" which I presume it means a web page is not allowed to store information outside of the browser app (Safari) and apps (your app) are not able to access information stored by other apps (Safari).
Our solution to this is to store this device to data key-value pair in an environment that is both accessible by the browser as well as by your app, i.e. your backend server.
The next challenge, which remains to be the biggest challenge, is how to uniquely identify this device from the information collectable from the browser? Javascripts in browsers, unlike native apps, don't have access to IDFAs which could be used to uniquely identify a iOS device. To overcome this, one can imagine to use a combination of common information that is available both to the browser app as well to your native app, i.e. OS type, public IP, screen size, etc. etc. Please note, a composite key from these data fields does not guarantee uniqueness (imagine two iPhone 6 visiting this web page via the same router). Therefore, your backend server (assuming you are using it to store this key-value pair), will want to have a strategy on how to handle collisions on keys i.e. the second key deletes the first key, or you allow collision to exist by having a queue of values for a single key. This really depends on how you actual plan to use this technology.
The last step is to form this composite key on your app using the exact same fields you used earlier in the browser to perform a "lookup" on your backend server to retrieve the value previously stored.
Here is a summary of the steps:
User 1 invites User 2 by sending the following link to 2: example.com?inviter=1
User 2 visit Web Page P
P constructs and sends the following key-value pair to your server S iOS|55.55.55.55|750×1334 -> inviter_id=1
User 2 goes to the app store and downloads your App A
User 2 first launches A, A contacts S with the same key (assuming the IP hasn't changed).
S finds the value inviter_id=1 by using this key passed in and, let's say, reward User 1 five points for inviting 2.
Hope this help!
Edit 04/24:
Since Derrick mentioned it in the comments, I figure I would take this chance to finish our story here.
Going back to the beginning of my answer where I mentioned we've attempted to do this ourselves. We had a working prototype based on our current system architecture (which is not in anyway optimized, or meant to be optimized, for storing and analyzing deep link data like this), we ultimately decided not to allocate any additional engineering resource into this project.
Due to the heuristic nature of this matching process, we found this project needing debugging, tuning and optimizing constantly for a diminishing ROI. More importantly, we have found other companies which are more specialized and do a much better job than ourselves.
It has been probably 6 months since we stopped using our internal system and we haven't regretted making such decision.
During this processes, we've worked with a number of vendors, Appsflyer, Adjust, TapStream and we have ultimately ended up with Branch Metrics https://branch.io.
Whether you should DIY or work with another company again depends on your specific objective. We finally decided to stay with Branch, not only because the other vendors charged anywhere from $500 to thousands of dollars per month while Branch is completely free, but also the level of the support they have provided is simply unparalleled.
We've successfully used the clipboard (NSPasteboard) to achieve this: the web page that processes the redirect to the app store does a paste to the mobile device's clipboard before letting the user download the app. Once the app is installed, it uses NSPasteboard on first launch to check for an appropriately coded string. This string can contain the text of interest or, more securely, a token used to fetch interesting data from the backend. In Objective C:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *pasteboardString = pasteboard.string;
The clipboard can be cleared once the app is done with it, to avoid repeating the same action.
There is a good solution here: http://blogs.innovationm.com/deferred-deep-linking-in-ios-with-universal-link/
Basic workflow:
User selects domain link on web.
Link sets referral ID to cookie.
User redirected to app store.
On app launch, load referral page in SFSafariViewController.
Referral page checks for cookie and if it exists calls a deeplink into the app with the referral ID.
My answer from HERE
Apple no longer supports Deep Links. It is now called Universal Links and works a bit differently.
Source
Now that Apple no longer supports URI schemes for deep linking, developers must implement Universal Links in order to deep link properly on iOS. If you are already using URI schemes, check out our blog on transitioning to Universal Links.
From: HERE
And HERE is another article on Universal Links and what they are.

Store temporary data outside of iOS app

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.

Inviting users to an IOS app

After registration, our app prompts users to invite her friends (aka phone contacts) to use the app too. This allows us to send an email/sms to the useer's contacts with some sort of invitation key. Works fine for a web version app, just embed the key in the url you provide in the invitation.
I'm having trouble figuring out how to make this work smoothly with IOS only. It would be brilliant if I could send the invitee a link to appstore.apple.com/myapp?registrationKey=abcXYZ and have the key magically available to my app once it's installed, but I guess this is a lot to hope for?
The obvious way around this is to make the user manually enter their registration key on first launch, but this seems less reliable and (to my mind) adds friction to the UX.
Has anybody come up with something clever to get around this?
Here is what is flowing through my brain on how to solve this solution, please note, I have not vetted, psudeo-coded, coded, or applied this theory.
Since you will know who is being sent an invitation, save that data to your database with a relationship to the user sending and a unique id to the user being invited (email address if its in the contact's card). When new users sign up scan the database for invitations, if one is found present it to the user asking We're you referred by <existing user>? Once the new user selects their response continue through the registration process, updating the relationship table accordingly and applying any extra settings you need to for the referral.
This combines automatic referral tracking with referral codes for a basic, straight-forward, almost (but not quite) fool proof method to make sure referrals are linked to the right users.
As far as I can tell, the App Store provides an information firewall between an invitation and the installed app.
The closest workaround I've seen is the following:
email link sends you to your website
the website logs reference information in the URL and the IP address
the website instantly redirects you to the App Store (if iOS detected)
user installs the app
user loads the app
app contacts your website, IP addresses matched ... BINGO
Obviously not a secure method though.
There are many failure cases:
business networks commonly share IPs
home and mobile networks release and reuse IPs
The more is frequently used to resolve cases where its good enough to know that the user 'almost-certainly' was referred to download app by the email.
For example, it can be a good mechanism to prompt the user with a "who do you know" question in an app and limit the options based on the (IP+reference) data. If they pick the original poster, then maybe that's good enough, and then you can attach any other data that the inviter provided.
(Full disclosure, currently work at Branch)
The best solution to this is to fingerprint a user. This requires you to do the following steps:
For each user, using your own domain, generate a link for said user. So, right when they complete registration, generate their unique URL, that contains the invitation key.
For anyone clicking this link, they will redirect to Safari first. When they do, capture their IP address and iOS operating system version from the headers and user-agent.
Save this data on your server, and set window.location to your iTunes url.
If the user downloads and consequently opens, inside AppDelegate.m, send a message to your server with the IP address + major/minor/min version you collect upon app launch. If it matches with what you have on the server, you can now pass that invitation key back to the new user.
It's not perfect, and has the ability to misattribute. You could also use branch.io, where all of this is taken care of (link-generation, fingerprinting a user, attribution). Branch also drops a first party cookie and ties it with the device level ID, so attributions are much more accurate.

Resources