Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
In my application I update the user data when the user logs out or closes the application.
The problem is that when he closes the application, the OS stops all the processes of the application, so I can't do my writing on Firebase.
What I want to do instead is save this data locally on the device and when the user logs back in, do the update.
I was going to save them via User Defaults but I thought that if the user had a jaibreak phone, they could theoretically access that memory area and therefore change values.
Am I getting the wrong idea?
Thanks :)
You are right, normally the sandbox of your app is protected but a super-user can access to it and read data. In this case, one solution is to prevent app-launching on rooted or jailbroken phone. There are some libs like this one to detect jailbroken phone. Some times it better to stop the app and launch a pop-up explaining why the app can't run on this phone because of cybersec rule.
But doing that keep in mind you will lost some users.
To your primary issue, writing data when the user leaves the app, this has several well-supported solutions. This is a canonical example of what beginBackgroundTask(expirationHandler:) is for. Whenever you begin a Firebase update, call beginBackgroundTask, and whenever you finish the update, call endBackgroundTask. That will tell the OS that you're currently performing an action that could benefit from a little more time before being terminated. You should expect something on the order of 30 seconds to a minute. (It used to be more like 3 minutes, but it's been tightened in newer OS versions.) That should be plenty of time for most updates.
If you are using URLSession directly, you can also make use of background tasks. See Downloading Files in the Background for details. This can be used to send data, not just transfer files. It has the major advantage of queuing operations when currently offline, and the OS will perform the transfer when possible, even if your app is no longer running. That said, this is all more complex to implement, and likely overkill for this kind of problem.
That said, if you're storing the access token anywhere in your program (including in memory), a user who reverse engineers your app can always connect to Firebase directly and send anything they want. Whether you store it in UserDefaults, in a file, or just in memory doesn't really change that. Also, last I checked, Firebase doesn't support certificate pinning if you're using their SDK, so a user can just rewrite your packets using a proxy anyway without even jailbreaking the phone.
I think that would be better to store user's data in cloud.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm learning how to parse JSON from web APIs. I have read that I need to asynchronously return my parsed data from the API for my application, as opposed to synchronously. I'm not sure why it has to be asynchronously. I know it has something to do with threading, but that doesn't clarify it for me.
Why do network requests have to be performed asynchronously?
The fact that you should to do this asynchonously has nothing to do with the nature of the response (JSON or otherwise). It’s just that you’re requesting data from an API on a remote server and you don’t know how long it will take (subject to the nature of the network the device is on, how busy the web server is, etc.).
Bottom line, any task that takes more than a few milliseconds should generally be performed asynchronously to ensure a responsive UI, and this API call will take much more time than that.
Analogy time
Imagine that you're employed in the information booth of a train station to manually update a board with trains' statuses. You read off an old-fashioned ticker tape and move models of the trains around so that passengers can see what's going on. You also answer questions about schedules and such directly, when passengers ask you.
You realize that for one particular portion of the board, some information is missing from your tape. Your colleague has the info, but she isn't in the station. So you leave the board, go over to the phone, and call her. You dial, and wait for her to pick up, and then explain what you need. She doesn't have what you need immediately to hand, so she asks you to wait a moment while she gets it.
Meanwhile, the tape doesn't stop. Information about trains continues to come in. but because you're sitting there on the phone waiting, you're not doing anything with it. The people who are watching the board get frustrated, and the people who have questions for you can't ask them either.
Finally, your colleage comes back and gives you what you asked for. You thank her and return to the board. You realize the board is in very bad shape, not reflecting the current state of the world at all. And the passengers with questions have stormed out and left you a one-star review on the App, I mean Train, Store.
Next day, the same situation comes up. You need information you don't have. Instead of stepping away from the board for several minutes, you quickly fire off a text message, and get right back to talking to passengers and moving things around on the board.
In about the same amount of time that you spent waiting on the phone yesterday, you get a text back from your colleague with the information. You incorporate it into your workflow, and nobody even notices that you spend a couple of seconds reading from your phone instead of the ticker tape. Victory!
The first day, you made a synchronous network request. You initiated a conversation with a remote service and waited until you got the response. When that happened, your UI was locked up, neither taking input from the user nor refreshing its own state.
The second day, you made an asynchronous request. You kept working normally until the response came back, allowing you to continue with all your other tasks.
My question involves keeping an app that monitors user interactions in the background, for example time spent in one or the app. The issue arises when you can not have a background process run for more than 10 min or violate Apple's sandbox restrictions. Since I am relatively new to the Apple API, and could not find a direct answer that didn't involve location services or VOIP (which are both interesting options, but my application will not be able to use either viably), I come to ask for options in which I can understand when another app opens, when it closes, when it fetches data, and when user holds phone in certain orientation (ie when people hold their phone at certain angles to read text and etc.) for certain amount of time.
The purpose of this analyzation is to predict an attention span for the user, so I need to be able to run in the background, as the user will not be using my app while it predicts attention span.
My thoughts on this are possibly accessing the system log, and somehow parse previous statements (I don't think sandbox will allow), but inevitably the iOS system will suspend my processes after some point unless I put a timer. There is also the option of having the system wake up my app via opportunistic fetching, but that won't be useful if I don't collect the data.
Keep in mind this is within IOS 11, so it is much more restrictive than previous iterations. I understand this may seem like a complex problem, but even a direction in which to head could be useful to me.
This solution might work, (not recommended since it drains the battery quicker).
Just update your current location, every 10 mins. It will reset the background thread timer.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I am a beginner and I have this little debate with my friend who is a Ruby and rails developer with more than five years experience, and has worked basically for the web, and I know the information he gets is from various presentations he have been to.
So, I am learning and bulding a project in the way. This project needs to get data from other devices and also send data from the administrator devices for the other users.
I want to build this app to be able to save data if the device for some reason is offline (the user will travel, and can find himself out of signal).
My friend says that I do not need t save data into the device, or not use CoreData, that I probably need some type of cache to save the data temporarily while the device is offline.
I tell him that this is not like a weather app where you only download the data and show it to the user, I need to make changes to the data and send it back to the server, so other users see the change.
So, my question is:
Do I need to use CoreData to save data locally when the device is offline and send a request to the serve parsing JSON?
Which is the best approach?
Thank you very much for your time and knowledge!
My friend says that I do not need t save data into the device, or not use CoreData, that I probably need some type of cache to save the data temporarily while the device is offline.
Where does your friend think the cache will be located if it isn't on the device? Caching but not saving data are contradictory ideas.
Core Data can be useful as an offline cache. There are other options, including saving property list files and using SQLite directly. Which one is best depends heavily on how you'll need to use the data in the app.
Do I need to use CoreData to save data locally when the device is offline, or use CoreData to save everything and send a request to the server using parse JSON file?
Keeping in mind that we don't have a detailed description of your app,
If the server provides JSON-formatted data, then you need to parse that.
If you want to use the data offline, you need to save it on the device somehow. Whether you call this a cache or not is meaningless.
Core Data is one possible approach. It might or might not be the right one, but that's a separate question that can't be answered without a lot more information about how your app uses this data.
A common approach would be to request data from the server and save it locally. When accessing data in the app, look it up in the local copy. Keep server communication and local data access separate; if they're the same thing then you're talking to the server directly for all data and have no offline access. Keep track of local changes so you can send them back to the server.
This question already has answers here:
iOS Make sure documents are open before accessing
(2 answers)
Closed 8 years ago.
My app depends on the UIManagedDocuments being open. Therefore I basically don't want the user to do anything unless the documents are open. The problem is that opening closed documents is asynchronous. What is the best way to go about this to make sure the user does not enter data to be saved before the UIManagedDocuments are open? I can think of two possible solutions:
1) Should I just wrap every call accessing the UIManagedDocuments in a check to see if it is open and run the code on the completion handler of opening a closed document? This way doesn't seem ideal because the user may do something and expect the results to be saved but it won't be saved yet.
2) The other approach I thought of is to stall the app somehow to wait for documents to open. But I read somewhere that it is bad to block the main thread to wait for the document to open. Can I somehow make the main thread do the opening itself? Or is that bad too?
Another question I have is, if I open all the documents upon loading my app (initial launch), will they stay open until the app is terminated? Or can the documents close at any time for undetermined reasons?
In short, you need to redesign your UI and/or stop using UIManagedDocument. Your Application Launch should be designed so that it can wait for the Core Data stack to be initialized. If you are not doing that now you need to redesign the launch of your application.
Further, UIManagedDocument should not be used as your primary Core Data stack. UIManagedDocument should only be used when you are building a document based application. If you build a proper Core Data stack yourself you will eliminate the need for the asynchronous start up.
However you still want to disconnect your app launch from the data display because of migrations, iCloud integration, etc. All of which can take human perceivable amounts of time and you don't want them blocking the UI.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Today they rejected my app and wanted demo user info to log in and manually test the app. I don't want to create a demo user on prod environment and give permission to make silly actions of testers. All users are connected to each other and the tester actions will be seen by other users. How can I manage this and what was your strategy for this kind of situation?
Addition: I don't want to write additional code and test it for a successful iPhone review. It doesn't make sense. We have a test environment. How can I use this environment for review purpose?
What we sometimes do is that we implement a test user whose actions get wiped out/deleted after a pre-determined amount of time (1 hour, 1 day, depending on the sensitivity of the environment).
I don't think there's any way round their request. It's something of a black box, but I don't think they have the time to do much more than test the normal functionality that users would expect plus a few edge cases (how the app reacts to phone calls, etc.) so I'm not sure what you are expecting to see. Your best bet if you don't want to change any code would seem to be to set your release date to manual (rather than the app being released as soon as they have completed the review) and then to reset your production server before confirming release. No other users will be able to download the app and interact with it until it has been released. You may still have to provide a test account for updates though.
You have two choices:
1) Make a special account that will not save its changes to the server
2) Don't publish the app on the app store