How does snapchat do their friends functionality? - ios

So I am trying to have users in my app find each other via their address book (a la Snapchat). How do I go about this?
I can have access to the user's address book so I would be able to associate each number with a user (I verify this via text for each user). Once I have all these users associated though, would I have to compare each phone number to my data base (Parse) in order to have a section of "Friends who have MyApp"? Otherwise, how can I grab an address book of X user and tell them which of his contacts have the App already installed?
Also, I have read in many places I should not upload their contacts info to my backend.
Help?

First thing that comes to my mind is to store each user's phone number as well. However, you might be right about not to upload their contacts to your server even though you do ask for confirmation that you're going to access their contact list.
I'll put forward another idea, how about storing their contact list as encrypted data? Thus, even you personally won't be able to reach any of the contact info. Use an irreversible encryption algorithm like sha512 and then store these phone numbers as encrypted strings. Each time a user requests if his/her contacts are exist in your database, encrypt each phone number locally and make a request if those strings exist in your DB. This implementation is really similar to common password storing techniques and I believe it is quite secure -and ethical.
Related: How can I compute a SHA-2 (ideally SHA 256 or SHA 512) hash in iOS?

Related

CloudKit: can't discover identities

Pretty new to CloudKit. Trying to get all the contacts who are using my app. According to the docs and the tutorials out there I'm calling this:
discoverAllIdentities(completionHandler:)
The issue is that only my user (the one who is logged in on the device where the app is running) is returned. So I did some digging and noticed that if I call this one:
discoverUserIdentity(withPhoneNumber:completionHandler:)
and I use phone number directly the user is returned.
So after more investigation, I figured that the reason I do not get those users is that in my Contacts those users do not have their iCloud email stored. So once I add the email, they are returned by discoverAllIdentities(completionHandler:). So it appears the default implementation of that method is tied to iCloud emails for the discovery instead of phone number.
Is it possible to use phone number for discoverAllIdentities(completionHandler:)? Since, I don't think that as you add a new contact you would record anything but just phone number, so you will be missing to discover all those users.
Any kind of help is highly appreciated.

Can CloudKit user phone numbers be retrieved using `CKDiscoverAllUserIdentitiesOperation`?

Background
I am retrieving all the users for my app using the recommended CloudKit operation, CKDiscoverAllUserIdentitiesOperation.
This operation is designed to returns each user's info in a CKUserIdentity object. The lookupInfo attribute of the user identity has fields that can contain the user's email address and the user's phone number.
e.g.
user.lookupInfo.phoneNumber
user.lookupInfo.emailAddress
Question
When I run this operation, I only ever get each user's email address. The phoneNumber field is never populated.
How do I retrieve these user identities and have them include the user's phone number? (Is this possible?)
Additional Info
I am able to retrieve individual users with their phone numbers using the discoverUserIdentity(withPhoneNumber... CloudKit function, so I know that these accounts are linked to phone numbers.
All you get is the email. That's it. It's not possible to get any more info than that using CKDiscoverAllUserIdentitiesOperation. And that is only for users that have agreed to be looked up via email while using your app.
The only time the phone number is filled in is if you specifically lookup the user by phone number. Of course that's kind of pointless since you already know the phone number.

Getting contacts who own an iDevice

Is there a way through addressbookUi framework to get only the contacts who own an iDevice? The check for example is done in the messages app for iMessage. But is this available for developers? Or is there another way to check for this? Thank you in advance..
You could check, for each address book record, if there is a phone number of type "iPhone" (represented by the constant kABPersonPhoneIPhoneLabel). There's really no way of knowing for sure which of the contacts "owns an iDevice" anyway, but if there is an iPhone number for them in the address book record, then there's a good chance of them using an iPhone. Of course, it's another story altogether how that information got in your address book, and whether it is reliable.
No there isn't... The SMS app would be checking with apples servers to see if the phone number is registered with iMessage or not.
This is not a publicly accessible API.
I guess you could hash then send the users number to your own remote database and then compare contact numbers in another users address book against your database to see if they are users of your app... It's not really what you asked to do but it's the closest solution I could think up

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.

How do apps like Path and Instagram tell if contacts are also using the app?

I am interested in building an app that has a Find Friends by contacts function similar to Path's or Instagram's but am not sure how it's done.
I know Path and Instagram upload your address book to their server, but how are they able to tell if a particular contact is also using the app? Does it also upload the user's phone number and thus match by phone numbers?
CLARIFICATION: I do not save email addresses (or any info other than the contact's phone number) in my address book, yet somehow Path and Instagram are able to tell if that phone number belongs to a user on Path / Instagram. How is this?
There are two join points between your address book and theirs:
Your e-mail address (and phone number).
Your friends address books that contain your e-mail address (and phone number).
Basically, just because you don't have their e-mail address listed doesn't mean they don't have yours listed. They could also filter this "who has your e-mail in their address book" based on the names and/or phone numbers in your address book.
Yes, it could also be joining on phone number. The point here is that there are many ways to join data together, and your phone doesn't have the complete picture of what they have.

Resources