Maintaining user data in an iOS app - ios

I'm in the final stretch of building my first iOS app and I wanted to know the best practices for passing around the user or not. Do I pass the user to every controller or is there a store-like infrastructure I can set up to store all runtime data in, or do I fetch from local storage every time I need the user?
Also when I close my simulator, the user is logged out of my backend. Does that mean that I should store the user password in local storage to sign them back if they have logged in before or is that bad practice?
If these questions have been answered else where please send me a link to a discussion along these lines.

Related

Transparent login with the Realm Mobile Platform

I'm moving an app from using CloudKit sync to using the Realm Mobile Platform.
I want the login process to be transparent to the user, so I'm using CloudKit authentication, this way they don't have to worry about creating an account or remembering a password. Of course if the user doesn't have an iCloud account set up, the data will not sync, but that's how the app is already working without realm: we just alert the user to the fact that the data will not sync because an iCloud account could not be found.
I noticed in the documentation that in order to open the synchronized realm, I have to provide the user's credentials.
My question is: how do I handle the case where the first time the user launches the app he doesn't have internet connection or doesn't have an iCloud account setup? I would like to just store the data locally if the user doesn't have an iCloud account (this is how the app works currently), but if I understand it correctly, the only way I can open the synchronized realm is to have the user's credentials, which I need internet access and an iCloud account to be set up on the device to get. Is there an easy way to handle that case with realm?
I know I could have a separate offline storage and move its data to the synced realm once on-line, but that would be tricky to get right and quite a bit of work.
Unfortunately you are correct: the very first time the user logs in to the Realm Object Server (via +[SyncUser logInWithCredentials:...]), the user needs to already have whatever identity provider account they're going to use (in your case, an iCloud account), as well as Internet connectivity.
Once the user's logged in at least once, their Realm credentials are persisted internally and the user can be used subsequently to open up Realms immediately, even if there is no connectivity.
The best workaround right now is to use a non-synced Realm to store whatever data you need before you have an opportunity to log in, and then manually copy the data over to your synchronized Realm once you are able to log in the user successfully and open the synced Realm with the user.
We know this is a pain point for a lot of our users, and plan to address this deficiency in the near future with features to let you immediately start using 'synced' Realms before a user has logged in.

Bypass login if user already created account

the reason I am asking this question is because I am not using firebase or parse to create accounts. I have used my own code to use CloudKit to login and so on. My question is, after the first time opening the app, and the user making an account, how can I make sure that the following time they open the app, it bypasses the login page? And then, if they logout, the next time they open the app, it takes them to the login page. How can this be done.
TL;DR how can I track whether or not a user has been logged in, and then open the app to a 2 possible scenes based on whether or not they are or are not logged in.
Firstly, you could keep the user sign in data (like a returned authkey, or a boolean flag) in the Defaults for the app.
Secondly, you could make a "Loading View" where you would check if that data is present.
Lastly, if the data isn't present move him to the login view, else to the main app.

Storing log-in details for Xamarin iOS app

I am getting started with Xamarin iOS and writing an app that requires the user to log in, using their phone number (which can hopefully be pulled from the phone via API). What I would like is the first time they use the app, to see log in and sign up buttons. Sign up takes them through a storyboard to enter information which ends up saving their details in my server database so their account is now open. Log in will check if their phone number is registered and if so, sign them in to the app based on their phone number.
However if the app closes or the phone restarts, I would like them to be automatically logged in the next time they open the app, if they have previously created an account.
I am reading a lot of tutorials on sign up/login screens but none talk about how to have an "automatic" log-in option once they have authenticated, at least until they manually click the log out button. Lots of apps do this so Im sure it should be trivial, can anyone point me in the right direction? Do I have to store a value in the iOS file system or preferences folder structure? Maintain a local iOS DB with these settings?
iOS has a NSUserDefaults class that let's you store small bits of user configuration data in a persistent manner.
You can also use the iOS Keychain to securely store user credentials.

IOS Where To Persist Current User from Back-end

I am using an IOS app with a Rails Back-end. When the user opens the app, I want to query its profile from the server and set a current user method in order to call it somewhere else in the app without querying it again from the server.
I would also like to store it so that the profile is saved to the disk and can viewed offline, including the profile picture.
What is a good storage solution for the current user and its profile picture? The different solutions I am thinking about are Core Data (because I already use in the app), and NSKeyedArchiver.
Any recommendations or ideas on which solution to adopt?

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