client-server fetch large data - ios

I have a application need a list of data, but these data may be very large. If I'm going to show this list of data in client (mobile app), I can't get all of the data from server because the limit space of mobile.
For example, like Facebook app, there are tons of newsfeed in server, and user can only see some of them. If user want to see more, they need to scroll down and fresh. So how to implement something like this in both client and server? (Currently my server is written in ruby on rails, and client is iOS)
And once the client get those data, does it store in memory or in local database? I'm worried about memory limit in mobile phones.
Thanks

On the server-side, you could probably write an API supporting pagination and custom results count, i.e.: myapp.com/api/get?start=0&count=20 to get the first 20 results, and when the user scrolls all the way down your view on the iPhone, fetch the next items, like that: myapp.com/api/get?start=20&count=20.
If you plan your design well, you'll get something very flexible that you'll be able to change later if you realize that 20 results is too much/not enough, etc.
Depending on your app's architecture and the amount of data your app will handle, you might also need to provide API methods based on the last-updated time, to ensure you're not missing data (e.g., if you call your second get?start=20 a few minutes after the first one, the start index might not have the same meaning).
As for storing data locally, it all depends on what you want to achieve. Are you sure you need to save everything the user has downloaded? You could store only the most recently fetched items in a local SQLite database and query them the next time your app starts up, before refreshing the view (I don't know how it is implemented in Facebook's iPhone app but at least it looks like it's done that way).

Related

How to ensure data consistency and truly take advantage of Core Data?

I've worked on several iOS apps, some of them utilize Core Data, and some of them don't. While I consider myself having a basic to somewhat good understanding of Core Data, there's always something that makes me doubt the usefulness of it. I've done a lot of reading on the subject, and the general consensus seems to be the advantages of using it outweighs the disadvantages. I recently submitted an app without using Core Data, and always planned on going back to update the project to utilize it when I have the time for some optimization work. Now's the time, but I wonder if it makes sense for the app I'm working on, and maybe I am not using it correctly all along. Please advise and point out what I am missing.
The project I am working on is a social networking app, which also has a front-end site. We have standard features like a newsfeed, event listing, the ability to follow/unfollow someone, and a map with POIs at user's location. Currently, we're using pagination whenever needed when requesting data from server.
My understanding of why Core Data is great:
Easier to manage data with complicated relationship
Easier to access data without having to pass them around
Easier to manipulate, fetch, and sort your data
Better memory utilization
Improve perceived performance by preloading data stored locally until latest data's received
The problem I am having is, since I am using pagination when requesting for data instead of requesting for all at once. The data stored locally is only a subset of the current state in the database. Let's use newsfeed as an example. If I do the following, it will cause some problems:
User manually refresh the newsfeed -> Controller notifies model that it needs the latest 20 items -> Model requests for the latest 20 items in the newsfeed and save them as NSManagedObject -> Model notifies controller that data is ready -> Fetch the latest 20 items to show in UITableView
If user A refreshes the newsfeed, background the app, and then user B deletes his post in the newsfeed (let's say it was 10th item) before user A foregrounds the app again to refresh the newsfeed. In user A's newsfeed, B's post will still be up there because according to the createdAt attribute, it's indeed one of the latest 20 items.
To fix this problem, I can think of a few solutions:
Add a flag to the item to indicate it's removed
Always discard local data when new data arrives
Disable pagination
Instead of using the workflow described above, always present the requested data only instead of fetching the latest
Solution 1 means custom code is required to deal with different clients since browser doesn't need deleted items but iOS client does. However, even though it can work, it can potentially mess up the pagination mechanism and can cause weird behaviours in the client. For example, if a large amount of items gets removed, the latest 20 items will contain only a few items that will actually show up in the newsfeed on the client when user refreshes it. As user follows more people, more stories will be inserted in his newsfeed as well. This solution won't work very well in this situation.
Solution 2 totally defeats the purpose of using Core Data in the first place unless I am missing something.
Solution 3 means the client always needs to request for all data. This is nearly impossible to do because as you get more data, the time to retrieve and process them will make the app slow and unresponsive. It also doesn't make sense from technical and UX point of view.
Solution 4 also kinda defeats the purpose of using Core Data because it's the same workflow when we only store data in memory. You can still fetch and find objects but they might be invalid on the server already at the time of access.
Am I missing something? How is Core Data supposed to be used in this scenario? How do you ensure data consistency when the client doesn't have all the data? Thanks you in advance.

Handling data request in app, best practice

I am trying to build a iOS based NEWS app. I went through some of the best NEWS app and found out that, when I tap on any menus like Home(for ex.), they request for home data, only once, next time when i tap Home, I think they display cached data because I don't see any sign of request for data, maintaining speed in app.
So how do they maintain the app with recent data, because every time if cached data is displayed, the data may be already changed in server which may not reflect in the app. So what is the best way to handle data request in apps. Is it like I should request data on every tap of menu buttons or should I maintain some timer to request recent data from the server and rest of the time display cached data.
Use CoreData for caching the news and store the timestamp as well and before displaying it to the user, check for the timestamp. If the last updated time is older than 'x' minutes, get the data from server.
Also, you can store the last updated time of the news articles on the server and create an API to just return the article IDs and their timestamps. Then in your app, first query for the time stamps, and fetch only those articles which are missing in your DB or with older timestamps.
The simplest and most popular way is to use Great Http libraries like AFNetwork
or ASIHttp.
This libraries provide support for caching in the most recommended way.
By setting simple cachePolicy you can easily achieve your purpose.
Its not just about caching it can handle many hidden http complexities on its own (cookies,https authentication,Not-Modified http header many more).
I strongly recommend you to use this way as i have already done some of the ios news reading app.

Storing data locally or just using ajax on mobile devices? - appcelerator

Currently I'm building a few mobile apps (currently on iOS but later on Android)that retrieve information via ajax calls (returning JSON) from a Ruby on Rails application. This obviously applies to other applications as well that are using another source to return the JSON data.
The main question is WHEN to store the data and when to just use ajax calls to retrieve it. Currently, my apps do not store a single thing locally and instead require ajax calls for all data. I think for this example we can use the Twitter mobile app, which is one a lot of people are familiar with and has a lot of functionality that I'm wondering how they do it (more logically than technically).
Questions:
1) When you log in the first thing you see is a list of all of the items in your stream. That list is available offline. Does that mean that when you originally signed in, Twitter already went and pulled all of your last X (100?) stream items into a local database and then future views just pull it from there?
2) If you then put your phone on airplane mode (or just shut off mobile data) and click one of those tweets, it opens up the tweet page with all of that data. So now, it looks like they aren't pulling that information in via individually each time you visit a tweet page (which is what my app currently does and takes some time to load that data in and create the views). Does it make sense that they are probably just using the same information that they pulled in when creating your stream items?
3) Users. Is it better practice to (when viewing a users "profile" page for example) store a users data locally and then refresh on future visits, or just do pull in all of the data via ajax each time? In theory each requires an ajax call...
I think those are my main questions for now. If anyone has any thoughts on any of those things (or any other insights into mobile storage) that would be great! If anyone needs screenshots of anything I referenced please let me know and I'd be happy to get those for you.
Currently using:
Titanium Appcelerator for iOS
Ruby on Rails for Backend and remote storage
Ok firstly there is a difference between local storage and device cache.
Mobile phones cache a lot of data so that it doesn't have to be requested each time using up your data plans. Its the same idea when you open a page on safari, go to home screen and go back into safari its still there. This wasn't saved locally its just been cached by IOS.
When you should use local storage is when the data never changes, using twitter as an example like you have, on first start up it downloads your current activity, if one of those contains a link then it will generate a new request, if you have turned off cellular data and still been able to click a link, this is not because twitter has stored it locally but because IOS has cached it temporarily to avoid downloading multiple times. twitter may very well store some of you activity locally, but at least from what I've seen it stores a maximum limit of them starting with most recent, it downloads the rest frequently.
generally speaking if the data is based on the web its fine to use ajax calls, that is what most do, local storage is when the data is only created / viewed on the device (like an app for taking down notes). If you wish to provide local storage so that someone can view there activity offline, great but this is a feature not a requirement.
Most people would only start thinking about this if users frequently request the same data over and over and its not going to change often, then you would need to develop a last modified system, where you send an ajax call to see is there anything new, if not read from local. If the data is dynamic and subject to change often, stick with the ajax calls

iOS: tableview app and database

I want to create a jokes application where jokes can be voted up and down and have ratings.
There is also different categories for the jokes.
My question is how should I store the jokes database?
The jokes database will be growing as application is updated. Do I want to store it on the phone or let the users grab the joke off a database in the web?
If the first option, what is the maximum capacity of text can I store on the iOS app? (In this case, I assume that jokes database will be updated as I update the app)
If the second option, how is this done? I can think of a couple of options, but they aren't really good.
1. store the database on a webpage and just grab it from there (but users cant vote up and down on the jokes)
2. create a mobile website that has all the jokes implemented like a real website, and use webview to show the jokes page to the user. (will probably need a log in system so users cant abuse the votes)
In these two cases, it is unsafe, because someone can just find out where my jokes are hosted by doing a google search and take all my content.
What do you recommend?
The most scalable solution is to build your own backend and fetch data from it on the phone. Application updates should be used for deploying code updates, not content updates. If you want a growing database of jokes to be available to the user, you're going to need a database stored somewhere on the web.
This approach requires you to set up your own webserver with a jokes database (using something like SQL or Postgres). You can use PHP, Ruby on Rails, Django, or other such server-side technologies to process incoming requests and fetch data from the database. The server would then vend this data back to the phone in a network-friendly format like JSON.
On the iPhone side, you can use NSURLRequest and NSURLRequestDelegate to make an asynchronous request to the server. For example, if you wanted to fetch all the jokes from the backend, you might make a GET request to http://www.yoursite.com/jokes. The backend will receive the request, use SQL queries to fetch the jokes, format the data as JSON, and send it back over the network to the phone. The phone can then parse the JSON (there a numerous JSON libraries for Cocoa Touch development) and update the display. To allow users to vote on jokes, you can similarly make POST requests to the backend, which will modify the data in the database.
Here's a simple example of how to work with JSON on the iPhone side: http://mobile.tutsplus.com/tutorials/iphone/iphone-json-twitter-api/

iPhone Data Best Practices - caching vs remote

I'm developing an iPhone app that uses a user account and a web API to get results (json) from a website. The results are a list of user's events.
Just looking for some advice or strategies - when to cache and when to make an api call... and if the iPhone SDK has anything built in to handle these scenarios.
When I get the results from the server, they populate an array in a controller. In the UI, you can go from a table listing view, to a view of an individual event result - so two controllers share a reference to the same event object.
What gets tricky is that a user can change the details of an event. In this case I make a copy of the local Event object for the user's changes, in case they make an error. If the api call successfully goes through and updates that event on the server, I take these local changes from the Event copy and set the original Event object to match with setters.
I have the original controller observing if any change is made to the local Event object so that it can reflect it in the UI.
Is this the right way of doing things? I don't want to make too many API calls to reload data from the server, But after a user makes an update should I be pulling down the list again with the API call?
...I want to be careful that my local objects don't become out of sync with the remote.
Any advice is appreciated.
I took a similar approach with an app I built. I simply made a duplicate version of the remote data model with Core Data, and I use etags on the backend to prevent sync issues (in my case, it's okay to create duplicate records).
It sounds like you're taking a good approach to this.
Some time back, I developed an iOS app where in, I had almost same requirement to store data on server as well as locally to avoid several network call and also user can see their information without any delay.
In that app, user can store photos, nodes, checkIns and social media post and with all this data, app can form a beautiful timeline. So what we did was, we had everything locally and whenever user phone come in some WIFI zone, we start uploading that data to server and sync both (local and remote) databases.
Note this method works well when only one user can access this data.

Resources