More connections or download bigger data - ios

What is more efficient? Divide the data into more connections or just put it all into one big connection?
Lets say we have a tableview which show a name of a person, when you select one row you move to another VC which show more info and in that view you can press a button to get even more info about that person.
Is it better to on the first VC to download ALL information for EVERY person in one big json and then use that to load the next views.
Or is it better to download on the first view just the names and maybe an id. And when you select a row you send that id to the server to download more info about just that person and so on.
My practical experience is that connections sometimes doesnt succeed so more connections could be dangerous, but the other way you only download the data you need.
What is the preferred method?

In my opinion best practice is to lazy load. Make connections as and when they are necessary.
I take your point about 'connections failing' and, to a certain extent, that's true of mobile connections. However, in addition to a slower user interface, another caveat of 'one big download' is the fact that potentially by the time the user interacts with the data it's stale.

Related

iOS - Constant listening to database update implementation

I have a project where I have 4 tab bars, and when i switched tabs, my api to get the API request to update my view is in the method viewDidAppear().
However this will make a very bad UX experience for user as whenever they switch tab, a loading icon and some times it load for 0.5 seconds but that instant appearance and disappearance of the loading icon is really bad for UX perspective. How can i implement a view where whenever the database value change, my view is automatically updating itself?
I have thought of using Timer() to implement where it calls the api every second but this is not practical as it will be constantly calling the API every second.
Does anyone have any suggestion? Thank you
There's a lot to unpack here, but I'll try to provide a generalized answer and point to several possible solutions to the UX problem.
There's several aspects that can play a role here:
Do you control the backend the data comes from, i.e. is it possible to follow paiv's comment and implement push notification? Or perhaps use some other means than pure HTTP(S) requests, like a websocket?
How frequently does data change? Is it realistic that it does so in between switching from one tab to another?
On that note, what do you do when data changes while your user is on one tab? Does that get refreshed in any way? Is it a problem if they don't get informed about this immediately? Is there a refresh button?
Do you persist the data beyond a view's on-screen time at all? Is it scrapped when a user re-visits a tab, i.e. does a tab always start "empty" until the API response is handled or do users see the values from the last time they visited that tab?
What best to do depends a lot on the exact answers to these questions. If you cannot enable the backend to do anything besides serving HTTP requests AND have to keep all data up-to-date constantly then obviously you have to do something like the polling you described. The update-interval depends on how important this is for your users. Even if it is 1 second, be aware that this means they could visit a tab before the next update has been fetched.
If you can adapt the backend and up-to-date data is a must, then push notifications or perhaps websockets are a way to go (keep in mind that websockets mean one open-connection per active user then!).
Push notifications would probably break down when the update interval is too high (i.e. if data gets changed in the backend very quickly and you keep spamming them), but would work nicely otherwise, plus they would update views that are already on screen if used correctly.
In 90 % of the cases I've seen, however, going with regular HTTP requests and a properly designed UI is the best choice. Properly decoupling the UI code from the data loading code and the code that displays the data is also very important. Here's how I would handle this:
Properly persist the data in some way in the app that does not require on views owning the data alone. If you want to persist beyond app runtime that means CoreData (or an equivalent), otherwise an in memory storage may be fine (that is kind of a global state then).
In your UI, show any data you currently have, even if it is "outdated" (in your case: "left over from the last time the user was on this tab"). Design the UI so that this is clearly apparent (grey it out, put tiny activity indicators next to the data while it is being loaded anew/updated, or something similar).
As said in 2. do show if the app is loading data. Initiating the loading when the users go to a tab is okay, but don't make a UI that is completely dominated by it (like one giant, empty view with a spinner on it).
Functionally, the loading should not directly update any views, instead it writes new data to your storage and just informs views and view controllers that they need to update themselves (if you're using CoreData and/or Combine you get a lot of this logic basically for free, especially for a SwiftUI app).
Such a design also lends itself to later being adapted for push notifications: While at first the re-loading is triggered by a tab switch (or a "refresh" button, for example), once (silent) PNs are available, they trigger the reloading. Even websockets can be integrated into this more or less, though there's probably a bit more to do that.
In any way, as said it all depends on your use-case and also available resources, but the gist of it is probably "If the current loading icon you have destroys the UX, redesign it properly". My gut feeling here would be that anything else might be over-engineering for your needs...

What is the best way to implement dynamic search on the server from iOS application?

I'm struggling with a problem of implementing dynamic search.
Here what i want to achieve:
In my application there is an option that user (program manager) will be able to search his team members. Each PM has its account on the server side (web service) where it is a table team_members which contains all the team members that correspond to this manager.
Their amount can be more than hundreds.
And client side app which I develop has an option search team members.
I want to implement it dynamically:
e.g When the user print first letter a I make a query to the server and get all the matches with a letter: Antuan, BArrow, etc.
Then user print ab and I make a query which must return Abraham, Abdulla, etc. And so on. All the matching results is shown in UITableView.
HTTP query to server is made each time text in UITextField shanges. I implement it with dispatch_async: on UITextFieldTextDidChangeNotification I create a dispatch_async where i make an HTTP request with searchbar.text.
The problem: it works very slow. I often get an exception bad selector was sent to the instance.
So my question:
Why is my approach bad? What is a better solution for this?
Or dynamic search it is a VERY bad idea and I must do search only on clicking some button?
Thanks. I hope some experienced iOS developers will give me good advice.
Making an HTTP request every time someone types a character is probably never going to be fast enough (nor does it really make sense -- read on). For a certain size of list, the answer would be to pull over the whole list in the background as soon as you present the field (but before the user starts typing in it). Once you have the list, you can start matching, in memory, on the local device. "More than hundreds" isn't very specific, and it depends on network speed, but I'd guess that if your list is less than 50K in payload size, pulling the whole thing will be the easiest way.
If the list is too big for that to be practical, but the list limited by the first character the user types is not too big, then the best approach might be to wait for the first character, fire off your HTTP request asynchronously, and only start the dynamic match once you've received the response containing all items that start with that letter. One thing to keep in mind is this: if you have the list limited by the first character, that's the only HTTP request you ever have to make (unless the user changes the first character) because all possibilities starting with that letter will be in that list. From there, you can pare down the list locally without any further HTTP requests.
As for why you're getting exceptions, it's hard to say without seeing your actual code. Try setting an exception breakpoint in Xcode. This will allow you to stop in the debugger when the exception is thrown, which will show you what's causing it.

UITableView + Large web data source

I'm using a UITableView which hooks into a rest API.
On first launch the app retrieves the data the UITableView will display and parses it in to a Core Data database.
This works fine for small datasets. But when the dataset grows to above 300-500 items it does not perform very well. Taking minutes to finish downloading+parsing. The app isn't deadlocked during this time, but the user likely won't wait for the parsing to complete.
I then decided to use paging. So now, I only retrieve the latest 20 items, and then the user can click "Load more" to go back further. The data is cached.
This seems to work well except for one problem.
Because I'm not downloading all the data on each load, I cannot tell when an item has been deleted on the server and I cannot tell when an item has changed (say the title may have changed).
Can anyone provide me with any suggestions to resolve this?
Thanks.
We routinely request a similar number of items and display it in a table view. However in our case the API returns JSON and we store it in model objects, not Core Data. Once the data is downloaded it takes less than a second to go from JSON to appearing in the table. Core Data is a bad idea for anything that isn't actually a database, or that isn't preserved for a past a user session. But you need to identify which part of your transaction is actually taking the most time. In our case it's the backend behind the API, but once it shows up everything is quite fast.
Also, in our case the data is around 700K and we are going to GZIP it soon to minimize the network time even further.

Use of Global Model in ios APp

I am designing an app which manages a tank of hot water. The app makes RESTful API calls to a service to;
Obtain a profile of temperature at various layers in the tank.
Allow a user to work with a timer (like an immersion timer) custom control to set times to turn on/off heating elements.
So, as a first cut, I have two tabs in a nav controller;
1. A graphic, showing a picture of the tank, graduated to show temperature.
2. A custom control, like commercial domestic timers, with two concentric rings, allowing the user to point, and drag 30 minute slots to set times for heating elements.
I have both custom views working well. I'm afraid to say I'm stuck on a very simple point - even after reading all of Apple's ios docs, and would love some help.
The data server (A BeagleBone running embedded Linux) implements 2 sets of RESTful APIs, one dealing with tank temps, and the other set to read and to update timers.
Is it best to start the App with a view controller which instantiates a model, who issues the APIs, and displays "Loading...", then populate a single application wide data model.
Have each view controller (The image of the tank, and the timer controller) to populate their own (separate) model?
And the big question for me (despite years of working in Smalltalk, C++, Java...) what is the recommended way to ;
instantiate a view controller
load / display a view with a "busy"spinner if the model hasn't loaded
My app isn't complicated enough for GCD, or indeed KVO. This is basically, a "show a view, call a web service to read the data", "modify the data", "call a web service to replace the data"
Basically, I believe my question is, when a view comes on screen, what is best practice to determine that the controller has a model, or has a model which is still loading data?
Sorry for the long winded question.
You asked a very good question, about a very common task in an mobile app. My suggestions are
Since your two tabs really have no common data, the problem simply boils down to "how to initialize a view controller with remote data".
If user can't use your app without remote data,
simply show a loading view in [vc viewDidLoad], and start fetching data from server asynchronously; your vc should implement NSURLConnectionDelegate to listen to call back
when data is successfully fetched from server, dismiss the loading view, and render the data to user
if data fetch failed (due to bad network or server downtime), show alert view to user, and retry the data fetching; if fetching fails for several times, tell user to try again later
you can make the loading view more beautiful, to provide a better user experience; note the loading view should cover all the buttons/controls, so user can't mess up your app state during data fetching
If user can use your app without remote data, it's another story. You shouldn't use a loading view in that case, and should silently fetch data in background. Since this does not seem to be your case, I will not complicate the answer by this case.

Best way to load distant data

I'm currently developping an iPhone app and need your opinion.
First, I am developping it for a Football (soccer) Club. It contains many tabs (at least these ones) :
News (Where I am displaying last news posted, obviously)
Shop (Where the user can buy stadium seats, and maybe various goodies)
Don't know yet exactly (But it will be related to Facebook/Twitter or stuff like that)
For every of theses tabs, I need to download XML data (using initWithContentOfURL). Right. But, that's where my problem is. Should I :
Load every needed xml pages at application start-up, and display a nice loading screen ?
Load every needed xml pages at the exact instant the user needs it in the application ?
In the first case, I get a slower application startup, but then, a faster navigation between tabs.
In the second case, my application starts relatively faster (still needs to load News XML, that's the welcome tab), but switching between tabs won't be as fluent as the first case (only the first time the tab is opened, of course).
Any advice?
Take a look at ASIHttpRequest which does provide some pre built caching mechanisms for you that may be appropriate and generally make interacting with web services easier
Load only what you need when you need it.
Furthermore, I wouldn't use initWithContentsOfUrl. It's a synchronous call, and it will lock your app. Instead, use an NSURLConnection to get the data asynchronously.

Resources