Swift iOS - API data and cache - ios

my app is a blog. On each blog post page, I make a request to my server to get the relevant data. I'd also like to keep a view count each time the blog page is viewed.
I can do this on the backend when it receives a request. I'm not too sure how cache works in iOS, but my question is, if this data is cached on subsequent views, will this request still be made to the backend on each subsequent view?
Or should I explicitly make a background request in my ViewController to update the view count tally?

If you are using URLRequest to call your API, then you can set the cachePolicy so that if your backend responds with the correct caching headers then if nothing has changed it won't reload.
You may want to re-architect your API so that you don't have to load the whole blog post every time just to update the view count. Perhaps that should be a separate API call, which has its own caching policy (since it changes more frequently)

Related

How to make sure you only show updated data from Rest api

I've created and application and a paginated api which is hooked up to each other. However i'm a bit confused on what is best practice in terms of only showing updated data. For instance if i retrieve data one day and save it into my mobile database. How will the app the next day know that it should make a request and only show that particular data that just has been fetched from the database. Do i need to make somekind of flag or look at createdAt?
When making the request, include either the If-None-Match header with the local resource's ETag or the If-Modified-Since header with the date the local resource was requested.
Configure your server to look for the header and return a 304 Not Modified if the data hasn't changed. That will at least save you some traffic on the responses.
In addition, if the resource data is relatively static, or if the client can tolerate having stale client data, then you can add caching headers to your response. As long as the cached request is valid, the request will never leave your client.
Ideally, you want do design your API to support this where possible. For example, have the request "give me all things in 50 meters" return a list of URIs. Then the API will only have to hit the server for those URIs which are stale.

ios - How to fetch all the data from RESTful APIs?

I have implemented a RESTful API with few resources, for example:
/products/
/products/1
/products/2
/categories/
/categories/1
/categories/2
etc.
Now, I have been told that the app should mainly work offline, therefore I need to get all the data from the APIs and store it locally.
Since I am not providing a single chunk of data but there are different resources URI that needs to be called in order to get all the data I was wondering if this could be a problem.
How does this work? will there be many HTTP calls or one call will do everything?
What is the best approach in this case?
Are these endpoints in themselves?
/products
/categories
It's a pretty well established convention for those to return the entire collection. You could even add some request parameters for filtering etc.
Each URI represents single peace of data. The main idea of REST, instead of having randomly named setter and getter URLs and using GET for all the getters and POST for all the setters, we try to have the URLs identify resources, and then use the HTTP actions GET, POST, PUT and DELETE to do stuff to them.
So, using AFNetworking, for example, you get all benefits of this architecture.
Download model could look like:
Ask server for specified resource by get request
save response in background thread
ask for new peace of data
Of course, if you do not have ability to make new endpoint, that will download all stub, you must download it separately for each:
/products/
/products/1
/products/2
/categories/
/categories/1
/categories/2
Setting up your endpoints in this way will allow for a user of your app to retrieve a single product/category or a list of products/categories.
Here's what each of these API endpoints should do when they are called.
/products - returns a list of products
/categories - returns a list of categories
/products/:id - returns the product with the specified id
/categories/:id - returns the category with the specific id
As far as allowing the app to work mostly offline. The best approach is to do some caching on the client (app) side. Every time a call is made to one of these endpoints for the first time, the result should be stored somewhere on the client side. The next time that same request is made, the data has already been retrieved previously, so therefore no network call needs to be made and the app will work offline. However, the first call needs to have a network connection to be made.
This can be implemented with a dictionary, where the key is the request (/products, /categories/1, etc.) and the value is the result that is returned from the API request. Every time a request is made, your app should first check if the data exists already on the client side. If it does it does not need to make a network call to get it and can just return the data that's present on the cleint.

curious about NSURLCache

I'm curious about NSURLCache, NSURLRequest has some policy of cache,
like NSURLRequestUseProtocolCachePolicy, NSURLRequestReturnCacheDataElseLoad,
but after read them, either of them are using local cache data, or not using cache,
My question is if I want start a url request, first I wanna load cache and render ui, then continue interacting with server to grab latest data and refresh the ui, which policy is my choice?
If I understand correctly what you want to achieve (get data quickly from the cache to show in the UI even if it is outdated, then get the current data even if it is slow), you'd have to make two requests, using different cache policies. I'd start the second request only when the first one has finished, and examine the result of the first request first, because the data might not have been available in the cache, so the first request might already returned the uncached data that you wanted.

Rails application design: Queueing, Resque, Background Services, and Redis

I am designing a Rails app that takes in requests, uses data within the request to call a 3rd party web service, process the reply and then sends out a response to the original requestor and also issues a PUT request to yet another service.
I am trying to wrap my head around how to design this Rails app as it's different from the canonical Rails structure.
The objects are Lists and Tasks. Each List has many Tasks, and each Task belongs to a List.
The request I would get is something like:
http://myrailsapp.heroku.com/v1/lists?id=1&from=2012-02-12&to=2012-02-14&priority=high
In this example I am requesting tasks from 2/12/2012 to 2/14/2012 with a high priority in List #1
I would then issue a 3rd party web service call like this:
http://thirdpartywebservice.com/v1/lists?id=4128&from=2012-02-12&to=2012-02-14&priority=high
As you can see some processing was done on the data (id was changed in this case)
The results are then sent back to the requestor and to another web service via PUT.
My question is, how do I set up the Rails app to handle these types of behaviors? How does the controller structure change? This looks like a good use case for queues, how do I distribute multiple concurrent requests among queues?
For one thing I don't need data persistence (data can be discarded after the response is sent out) and also data structure design is simplified. (I don't think I need ruby objects, simply dictionaries or hashes representing these would be lighter weight and quicker to implement)
Edit
So I broke down the work flow of the app into these components
Parse incoming request
Construct 3rd part web service request
Send 3rd party request
Enqueue a worker to process the expected response
Process the response once it arrives
Send the parsed result back as a response
Which of the standard ruby controllers handle each of these steps? What are the models needed besides Lists and Tasks?
You should still use a database because passing data to Resque is messy. Rather, you should store it in the database and then pass the id to the workers, fetch the data, commit any new data or delete the record. It's really up to you but this method is cleaner. You can also use a push service like faye to let the user know when the processing is complete.
If you expect to have many concurrent requests, I would recommend Sidekiq as it's less of a memory hog. Having 4-5 resque workers can already suck up about 512 MB. The controller structure should not change. Please comment on anything you need clarified and I'll be happy to update my answer.
EDIT
You would want to use a separate database store, such as Postgres. Not sure if it's important what models you need, but essentially this is what should be happening.
In your controller, create a Request object which contains the query params you want to query this 3rd party service with. Then enqueue a job to be handled by Sidekiq/Resque, let's call this ThirdPartyRequest and pass in the id of the Request object you just created as an argument. Then render a view here showing the Request object. Let's say that Request#response is still empty cause it hasn't been processed yet, so let the user know it's still processing.
A worker then handles your job ThirdPartyRequest. ThirdPartyRequest should then fetch the Request object and obtain the query params needed to contact the third party service. It does that then gets a Request. Update the Request object with this Request then save it.
class ThirdPartyRequest
def self.perform(request_id)
request = Request.find(request_id)
# contact third party service
request.response = ...
request.save
end
end
The user can continually refresh his page to check on his/her Request object. Once it gets updated with the response, they will know its completed. If you want the page to refresh automatically, look into faye/juggernaut/private_pub or a SaaS solution like Pusher.

Notify when web site has been Changed

Is there any way to inform web site has been changed?one way is get all web page contex and compare it with previous contex!but Im looking for solution that notify web page changes without get page context!
The only way that you could tell a website had changed without accessing the content is for the website to notify you itself, through an API or RSS feed or similar mechanism.
Unless the site in question has a mechanism to actively notify you...
You don't necessarily need to get all site content, but you do need to make a request to the site. You can make a HEAD request to get only the headers. Depending on the site, these headers may contain information about when it was last modified.
Additionally, you can check for a response of 304 Not Modified if you have content cached. This is more often seen with a HEAD request than a GET request, but can be used either way. Like with any request, of course, it depends on how the server decides to respond.
You can look up the standards easily enough, and how you make use of these options depends on what technology you use. But basically a HEAD request is simply asking the server, "Don't send me the page, just send me some basic information about the page." And checking for a 304 response is basically asking the server, "This is when I last accessed this resource, has anything changed?"

Resources