iOS: How to save data over the complete lifecycle? - iphone

I have an iOS app with a login view.
I need to have the login-data the whole time until the user ends the app or click "logout".
How and where to store it?
Are something equel like "member variables" possible in iOS / objective C?

If you're going to be storing username/password data, it's probably best to store it in the keychain. If you're only looking to keep track of whether a user is logged in, then consider storing a flag of some kind in NSUserDefaults. You can clear data when the application exits through the applicationWillTerminate: method of your application delegate.

You could use NSUSerDefaults, but everything you save in NSUserDefaults stays there for ever unless you delete it. Id I understand i right, you want that the password ans login gets saved only when the app is opened, and when the app is being closed, that data gets deleted? With nsuserdefaults you will have to set #"" for the password and login in applicationwillterminate, to delete the data. Or you declare two NSStrings in you header file, and in the .m you do passwdstring = passwd.text
loginstring = login.text
what this does is it saves the data to two nsstrings, that data is available the whole time while the app is opened, when the user closes the app, and re opens it, the strings are nil again and when he logs in, the strings will have the loging info again.

Related

SwiftUI & Firestore

I am wanting to use Firestore to retrieve user info and other data linked to that user once they have logged in via firebase auth. On the home page of the app I use .onAppear{ pulluserData() }. I understand that Firestore functions are asynchronous so how can I wait for this data to be pulled before displaying it to the user on the home screen?
Here is my function to check the database:
func checkDatabase() async {
//Function that will check the database. Will be good to add a listener eventually
if self.pullUserData{
await dbm.readUser(userID: "VSWAq7QCw3dbGYwMdtClbbANGVe2")
}
}
and the actual database function:
func readUser(userID: String)async{
//Function that will be used to read user info from the database
let userRef = database.collection("users")
do{
let doc = try await userRef.document(userID).getDocument().data()
print("The doc is: ")
print(doc as Any)
}
catch {
}
}
There are a number of ways to do this but the two most common ways are to (1) use a launch screen to indicate a loading state that disappears to a view identical to the launch screen (to continue the appearance of loading) that is only removed when the database returns (i.e. Twitter); (2) load the user right into the app and allow them to move freely while either indicating that data is loading or displaying cached data.
Remember that Firestore maintains a local cache on the device which means that data will be available immediately when the app launches. This data may be out of sync with the server but it will update as soon as the app establishes a connection with Firestore, which is usually instant. What I would recommend is launching the user right into the app without the use of a loading screen and relying on the cached data to get the UI up as fast as possible.
And if we're only talking about user-specific data (data that is specific to the user that the user has full control over) then that data will only change when the user changes it, which would have been the last time they used the app, which means that the locally-cached data on their device (assuming they use only one device) will always reflect the state of the server (in theory, anyway). And if it doesn't then it doesn't; the fresh data will update instantly anyway.
You may then wonder what happens if the user launches the app without connection. In that case, the cached data is displayed and the user is almost none the wiser. And because Firestore is offline capable, the user can freely edit their data and it will write to the server when connection eventually establishes.

Typo3 extbase create global array

I am using the version TYPO3 9.5.13. If a user is doing a successful login, I store the user data in the controller. If the user comes back from any view to the same controller, the user information, saved in the controller before, are gone. So it seems, that every time the user comes back to the controller a new instance of controller will be opened. PHP globals in TYPO3 are not working.
Therefore I am looking for a way, to have some data always available in the ncontroller. The extension is my own, as well the templates and the views. So if neccessary, I can make any changes.
The only way I currently see, is to send the user data to the views and from the views back to the controller. But that is not easy possible for all my views and also not a elegant way to do.
Do you have any suggestions? Thanks for your support!
You should store your user data in a session variable. this data can be acceessed globaly and TYPO3 will manage it for you. it is available for each request of the client, until he logs out or ends his session (terminate browser, ...)
Thank to Bernd, I found a solution:
$GLOBALS['TSFE']->fe_user->setkey('ses','user',$Setup);
$GLOBALS['TSFE']->storeSessionData();
I stored an array under user. Important is the second line, to store the Session data.
With the below instruction I read it into an array.
$user['user'] = $GLOBALS['TSFE']->fe_user->getKey("ses", "user" );
It is possible to store several variables und of course to change the name user.
You can clear, if you write NULL to it:
$GLOBALS['TSFE']->fe_user->setkey('ses', 'user', NULL);
$GLOBALS['TSFE']->storeSessionData();

cloudkit: how to access main user's attributes?

I am trying to make an app in which every user would have a personal avatar, a nickname and so on.
I don't know how to access the user's account on cloudkit.
My solution would be to retrieve user's AppleID, query Cloudkit and modify the user's attribute... But I guess there should be a better way to do it. Isn't their something like NSUserDefault but for cloudkit?
You first have to find out what the current loged in userId is. You can do that by executing the fetchUserRecordIDWithCompletionHandler method on the container. Then you can get more (currently only first and last name) information by executing the discoverUserInfoWithUserRecordID on that container.
You could extend the Users table with extra custom fields, but I would not advice doing that. The Users table is a special system table with some limitations. It would be better to create a separate recordType with the user settings. Just add a CKReference to the users table for easy access.
You also have to be aware that a user could log out and log in with a different iCloud account during the operation of your app. You could capture this by executing the code below right after your application start. Of course you have to implement your own logic where you see the NSLog
var ubiquityIdentityDidChangeNotificationToken = NSNotificationCenter.defaultCenter().addObserverForName(NSUbiquityIdentityDidChangeNotification, object: nil, queue: nil) { _ in
NSLog("The user’s iCloud login changed: should refresh all user data.")
}

Continue uploading NSData even connection lost/user clicked on home NSUrlConnection

I need to upload via HTTP Post NSData which is UIImage or NSUrl of a video file via the iPhone app which I develop for ios6
I need to support the following cases:
The user clicked on home - to continue uploading in background
The connection is lost - to continue uploading when there is a new internet connection even if the user left the app by clicking on the home button)
The user quit the app (clicked on x) and it was in the middle of uploading, next time that he would open the app, it will continue
In case 2 and 3:
It will continue from the same location that it was in the NSData (not start from the beginning of the file)
It will send in the new call a variable index={index} (where index is the amount of times that it continues starting from 0
I know how to use NSURLConnection as an async connection. But how to support the above 3 cases?
For this to work you need 2 things:
A record, stored persistently, of how much data has been uploaded to the server.
A server which accepts the Content-Range header and can handle storing partial uploads and completing them later. (or a server with an API to handle the same function).
If you have both of these things then you can perform the task using NSURLConnection and its delegate methods, NSUserDefaults (or similar) to store the progress information and subdataWithRange: (or perhaps NSFileHandle) to get only the data which needs to be uploaded.
Look at using connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: to get updates of what data has been sent. Store that number (if not all of the data has been sent) into user defaults. Once all the data has been sent, remove the number from user defaults.
Use subdataWithRange: by creating a range from the stored number to the (total length of data - the number).

XCode: how to get the email of the user programmatically?

I would like to avoid to ask my user to fill in a field with his email (long and discouraging). Is there a way to get the email of the user in order to avoid that he has to write it ?
Thanks !!!
Ask first time, make user select remember me option through UISwitch, save it inside a plist (ENCRYPT and then SAVE IT). Next time read the plist. If user like to write every time then good for them, else they can user your given option to save it and then later you can complete the field automatically!
If you mean the apple ID email, then you cannot access it, you will have to ask the email explicitly