How to implement an iOS app personalized start page? - ios

I'm developing my first iOS app and I'm facing a challenge.
I'd like to present new users a personalized screen when the app starts at the first time. Let me explain more.
The flow should be more or less like this:
My app isn't installed on the user's device.
Then the user gets an SMS on his iPhone with a short message and a link to install my app. The message is part of a conversation. Another user of this app had sent this message (through my backend) in order to join this user to the conversation.
This install URL doesn't necesarrily link directly to the itunes store, it can link to a conversations specific link such as myapp.com/conv/12345
The page at myapp.com/conv/* will detect the device and if it's an iPhone would redirect the user to the appstore to install myapp.
The user then installs myapp and launches it.
Now I'd like to present the same conversation 12345 to the user, before he even needs to login, register or what have you. That's the difficult part... I don't want the user to start an a blank page, I'd like to take it right to the conversation 12345 page.
I assume steps 1-5 are easy, but I can't think of a way to implement 6. I admit that I'm not familiar enough with the intrinsic of the appstore but as far as my understanding goes, "all apps are made equal", I mean the app itself when it gets installed it has no context, it doesn't know what "caused" it to be installed, it isn't aware of the click on myapp.com/conv/12345. Is this correct?
If there was a way for an app to know something like a referrer URL for the instllation or something along these lines that would be awesome.
If there was a way for app to query the device for its phone number
then I could make this work (b/c the SMS was sent to a specific phone
number, so I can track the most recent conversation sent to this
number on my backend). But since apps are sandboxed, accessing the phone
number is off limit.
Well, I suppose I could ask the user to type a unique code from the SMS when the
app starts, say 12345 and then I'd be able to display the
conversation to him. But that's problematic in two ways, first,
security - the user can join a conversation not meant
for him, and second, that's less than optimal
user experience, I want this to work like magic, I don't want to make
users memorize and type strings into my app the first time they
install, I'm sure they won't appreciate it... (they could
copy-paste, but still...)
Another option is asking the user to type his phone number. But that
again has a few drawbacks, one is that again it's less than optimal
UX, I'm asking a user to type his phone number to an app he doesn't
yet know or trust, second I'll need to verify (authenticate) the
phone number, I mean what prevents that user from typing a phone
number that doesn't belong to him?
If I had access to the SMSs then I could dig up that code, but I find
it hard to believe that apps get access to SMSs, it's just sounds
like another reasonable sandbox restriction. Of course I'm not
speaking of jailbroken devices.
BTW, if the user just went over to the appstore to install my app (and didn't go through a conversation SMS) that's fine, in this case I'll just present a normal register/login page. The interesting case is where the user was already part of the conversation when receiving the SMS and now I want him to (effortlessly) become part of the same conversation through my app.
To sum up - is there a trick to present "personalized" pages the first time an app is installed and launched that would get that user right into the context of the conversation sent to him over SMS without having to request additional input?
Thanks!

It's impossible to do. Your application is installed without the knowledge you need whatsoever. As you pointed out, it's a reasonable sandboxing restriction.
What you could do is a challenge-response based system, but it would be about as intrusive to the user as is registering/login in.

Ran, you can keep a flag in NSUserDefaults (equivalent to Android's SharedPreferences)
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html

Related

How to send invitations to join a group from stand alone IOS app

I have a client who is requesting a feature that I'm not sure is possible as he describes it. He would like to send an invitation to one or more of his contacts via a text message, all from with in his stand alone app. That part would be fairly easy (I think). When the contact receives the text message containing the invitation and taps on it, one of two things happen:
1) if the recipient doesn't have the stand alone app on his device, he is directed to the App Store to download it. When the app is first run the user is added to the group that he was invited to. The app itself has UI that indicates that the user is a member of group .
2) If the user already had the app, he would simply be added to the group (if he accepts the invitation).I've looked into the Message and MessageUI frameworks. I'm not seeing a way to accomplish this task exactly. The text message would have to somehow contain data referencing the group info to be joined. And then actually configure the stand alone app with that group info - even if that means waiting for the app to be downloaded from the App Store first. Seems far fetched.
Does anyone have any pointers as to how this task may be accomplished?

Telegram geolocation

I have an idea to use a telegram bot for food ordering from a smartphone. So, you have a menu, prices, there is a payment gateway. This part seems clear to me.
I was wondering if there any way to get a geolocation information inside telegram? So smartphone owner location is sent automatically.
The alternative I see are:
writing address thru telegram (too much work and probably restaurant has to call back);
Install a small Android/iOS app just to send a location to the service. Kinda feels awkward, but a little better that first option.
Maybe you can see better ways, perhaps telegram already got some related functionality?
Thank you!
On some step (don't do it too early) you can send a button with the request_location field set to true.
When the user presses that button, Telegram asks the user if he wants to share his location with the bot.
The user then sends a location. Note that the user could also spoof the location.

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.

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

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.

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