Why do I need to asynchronously return data when dealing a web API? [closed] - ios

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.

Related

Is it safe to store data locally on a phone? [closed]

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.

Does Anyone Really Know The Time? (ha!) [closed]

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 6 years ago.
Improve this question
Can an iOS app access the time of events using the iOS clock?
This would seem to be a simple question… but couldn’t find anything on Google search or here on Stackoverflow either.
Q1. I’m doing a feasibility study on building an app that needs to record the precise moment an event occurs. For example, if an event in astronomy, nature (e.g. lightning) occurs at 16h18m22s (4:18pm, 22 seconds), and the app supports the user to record when the event occurs, can the exact time the user taps the button be recorded using the iOS clock as a time reference?
Q2. How much precision is offered by the iOS clock? Is it possible to record the event-time as a decimal of one second? Milliseconds?
For example: 16h18m22s50c (where the last two digits represent 50 centiseconds or 0.5 of a second).
Q3. Would it be safe to assume that, apart from timezone differences, that everyone’s iOS device is reading exactly the same time, what one might call "universal device time"?
Q4. Or if this approach using the iOS clock seems a bit clunky, especially where ultra accuracy is required, would it be smarter to get a feed from an atomic clock server?
Thanks for any input on this one. Appreciated!
Cheers
Q1: yes! Using [[NSDate date] timeIntervalSince1970] you get sub-millisecond precision
Q2: you are going to get milliseconds as explained in Q1.
Q3: Since timeIntervalSince1970 gives you exactly what it says (the time interval since 1970), yes - that is a property unaffected of timezones. (watch out for the but below)
Q4: using a server will destroy any way of retrieving an accurate result since you have to contact the server and wait for a response, that will take around 100ms which is far worse than every inaccuracy the device clock would have.
BUT
the user can change its device time which makes the measurement still exact but useless since it no longer reflect the actual time! What you can do in this case is
retrieve the current timestamp of the action on the device
contact a server with a properly set up clock
compare the measurement and ignore the measurement if it is too far off / alert the user to correct his system time. A comparison threshold of half a second should be okay unless your server is very far away or very slow.

Game Center vs Socket Programming&Server for iPhone App?

I have requirement of developing an Quiz Game but real time. I have read a little about it and went through some tutorials and documentations.
I have a queries in my mind regarding making it real time and effective.
I want to ask that
Whether I should use Game Center or Socket Programming where server is made in PHP/Asp.net or Python.
As, the architecture which I am thinking to make is looks like as below...
Architect…..
Download All Categories.
Select Subject, or Category/topic, every category can have many subjects.
After selecting, you will press button, Play now, it will send query to server, that you want to play., server will choose any one who also want to play and searching for some opponent
After both opponents are selected, it will send data to both, means in response of previous request, a user along with data of questions will be send.
As every question has fixed time, fixed score, so locally it will be shown and calculated and score will be sent to server and server will also show score to both players. means another data will be send, but very small data, say one string or two.
As time will be over, another request will be sent and final result will be displayed.
Thanks
Proper guidance will be appreciated.

flow of ios app using Corelocation [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I was wondering if anyone can explain the flow of an app using core location. I am building a GPS app that will pause (after a given delay set by the user) and then run through the iterations (also set by the user). But I am finding that it runs indefinitely. If I take the for loop out of the code I then get 2 responses back from location manager on my first search.
Effectively this is: user presses the "get location" button. This then calls our getlocation function but it loops twice through this and through the NSLog output I will always see 2 responses but only on the first loop.
Getting location updates is an asynchronous project and you need to wait for, then filter the results. The flow is:
Create a location manager and set your object as it's delegate.
Ask it to start updating your location
Return.
Then you will start receiving location updates. The first one will probably be "stale" (the timestamp on it will be from the last time the GPS was active.) Make your code reject any location update who's timestamp is more than 1/2 second greater than now to solve this problem.
Next, you will receive a series of location updates with really bad (unacceptably bad) horizontal accuracy readings. Check the accuracy reading and reject all readings that are not accurate enough for your purposes. (The accuracy reading is actually a radius value that defines a circle where the location might be, expressed in meters. Smaller is better.)
How accurate is accurate enough depends on your needs. If you can't get an accurate enough reading in a reasonable time (say 30 seconds) make sure you code a timeout that gives up and displays a "can't get an accurate reading" message to the user.
Once you either get a recent reading that's accurate enough, or time out, stop updating until the next time you need a location fix (or keep updating if your app requires that.)
You might want to write a test app that displays timestamps, map positions, accuracy readings, etc as they come in, and then walk around with your phone while it's running. It takes a fair amount of tinkering to get an algorithm that filters location updates the way you need it to.

Developing an app for ios i'm supposed to support fast or slow connection? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Strange question i know. I'm developing an app for ios for a target being the visitors of a commercial centre. The app provide an internal updating system, using an xml system, that for a long list of reasons works differently in the case of slow or fast response of the net. The difference stands in different type of malfunctioning of the ui, and i only can choose to have a better performance in the case the user have a slow connection OR a fast one, for the two solution (one for the problem on the fast case, one for the slow case) for the issue i have, involve one the presence of malfunctioning in the other case.
In this case, i'm supposed to favor users who belong a fast or slow connection and why?
Edit: I'll try to explain the problem. I have a view that need to be updated via xml. When i launch the view, the simple fact i try to access the xml to control if the update needs to be done, takes time. I added an activity indicator, but it doesn't work fine for, as the net gets slower, it seems to take more time to the activity indicator to show, with the result the user have to time to think the app is frozen, try to touch button he has not to touch (that will not work and make him think the app doesn't work) and so on. So i used performSelectorInBackground in order to add the activity indicator as fast i can and it works fine in the SLOW connection case. In the FAST connection case, the activity appear so fast that it appears even if the control if the update must be done, due to the speed of the connection, takes near no time, causing it to show the activity indicator for a picosecond, giving an awful graphical effect that is to be avoided. To avoid the problem in the FAST case i added a
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.000001 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{ code to add the activity indicator; });
and, in this way, i do not have the graphical problem of the FAST case, but in the SLOW case the execution of the dispatch_after (i guess) slow down the showing of the activity indicator too much causing the impression that the app freezed. So my hands are tied and i don't know what it's to prefer.
You can determine what type of connection user has (Edge/3G or Wi-Fi) and perform different methods for each type of connection. Sample code here. Usually wi-fi is faster and cheaper, so you can provide your "fast code" for it.
P.S. I am still not sure what are you talking about. Perfomance? Difficult to give proper advice without some details, but still:
1) You can download needed stuff in background.
2) If it's about menus with images/videos/music - start with downloading list with titles, after that download media files. (like android market does on slow connections).
EDIT:
First of all, don't mix views and network tasks. All downloading should be done outside of the ViewController, in another thread.
You can download new XML each N minutes (or use if-modified in your request) and show it next time user tries to see the view. How often do you get new XMLs? It's important, maybe you can avoid downloading it at the same moment with UI drawining. Good luck!
As the target is visitors of a commercial centre, you should always work with fast connection to give a better user experience .. user does not like to wait long time with a loading screen on the device .. but you should also tackle the negative scenario, i.e, slow connection. You need to determine an optimized time depending on requirement so that you need to show the loading screen for that particular time only and still, if the connection is slow, you can terminate the connection with a 'Try Again' message .

Resources