Storing array of data in cache iOS Swift - ios

In my app, i get the menu of the app through a web service. It around 423 number of records which changes rarely. What I need is to cache this record in the app after first time login and use the cached data. If there is any changes in the menu database then only it should refresh the menu content from web service again.
I am not very sure how i can achieve this. Currently I store all the records in an array of menu class and use directly, which is very time consuming as we are hitting the service call again and again for similar record. I am new to iOS development so any suggestions are most welcome.
Thanks!

Store the data in one of NSUserDefaults (if this is infrequent, but permanent config data), or NSCache (for ephemeral data), or CoreData (for permanent, performance-dependent data).
Load this cached data on app launch; if the cached data doesn't exist, retrieve it from your web service/API.
If you're not concerned with the data being up to date immediately after you change the menu content, use something like the Cache-Control header to set an invalidation time period (details). If you do want to ensure that the menu updates as soon as a new remote version is available, then you'll need to set up a versioning system where your app makes an API call to check the version of the menu and update if required.
Example scenario:
App launch
Load menu content from NSUserDefaults/CoreData/NSCache
Asynchronously check API for menu version
If new version of menu exists, asynchronously download and refresh the menu view
Save updated version of menu back to NSUserDefaults/CoreData/NSCache.

Related

getWorkItemRelations() not always return active data

I have a custom control that shows the hyperlinks related to the active Work item. To do this, I call the getWorkItemRelations() and almost always works fine. My problem is when I delete a Link and the refresh in my custom control is called the result array includes the deleted "Links". In the Link tab the deleted Link was removed.
I review the resulting array for a flag that indicates if the Link was deleted but it doesn't exists.
Also, I put a button to refresh the data in my custom control but the result is the same.
Are there a way that I can force to full reload the relationships for the Work Item?
This phenomenon maybe related to the data caches on client computers. You could give a try with refresh the Work Item Cache.
To update the cache for tracking work items, you invoke the
StampWorkitemCache Web method. This method forces client computers to update the cache the next time that they connect to the
application-tier server. This method also synchronizes the workspaces
that are defined on the client computers.
To refresh the cache for tracking work items on client computers:
On the new server, open Internet Explorer.
In the Address bar, enter the following address to connect to the
ClientService web service:
http:// PublicURL/VirtualDirectory :8080/WorkItemTracking/v3.0/ClientService.asmx
Choose StampWorkitemCache, and then choose Invoke.
Note: To invoke the StampWorkitemCache Web method, you must be a member of the Administrators security group on the application-tier server for Team Foundation.
More details info about the method please refer the official documentation: Refresh the Work Item Cache
Update
Every changes on the work item need to be saved. Unlike UI on the web,it's not a real-time display. You need to save the work item , then refresh in your custom control .

App structure iOS and Realm: create database when app is installed

I am very new to iOS. I am developing an app with data persistence. I have decided to use Realm for that purpose.
I must to create the database and load data the first time that app runs. I get data from a Web Service in JSON format. I will implement some strategy to update this database later, maybe with iOS Silent Push notifications.
I have read and I have worked about Realm, loading data from JSON... to learn about that.
Now, I need to apply this in my project but I don't know how to start. I need some clues about general idea for the app:
How can I organize my app to load data when it is installed? At what point should I create the database and load data?
I have thought to create a global Realm object y AppDelegate and use it as a global variable. Is it a good idea?
Do I need to set a path for my database? Can I user default path?
If you are looking for a place to start, you can check out the example apps of this UI component add-on for Realm: ABFRealmGridController.
The controller is a subclass of UICollectionView and the example app should demonstrate most of the functionality you are curious about. The example uses the controller to display the top news stories from the New York Times. This involves making a request to their API and loading the JSON response data into Realm.
When to load the data is dependent on how you want the app to function. If the data will be the same for each user, you could bundle the Realm file with the app pre-populated with data.
The ABFRealmGridController example loads data when the user clicks the refresh button and performs the JSON handling on a background thread; a general best-practice.
Finally, unless you have multiple Realms or need to store the file in a specific path, it is probably simplest to use the default path.

Every time I run an app I have to download new data

I'm developing an iPhone app with latest SDK and XCode 4.5.2.
This question may be valid for any mobile platform.
I need to connect to a web service when app stars and download some information. This information could change on server: some registers could be deleted, updated or inserted.
I problem is that I don't know where to store that information. I think it's a bad idea to store it on device memory. I think it's better to store on a text file or a database. What do you think?
I have another question is: How can I know if some data has been changed on server? I think it's a bad idea to download the same data every time user stars app.
If I want to do this, connect to web service at star up, when splash screen is shown. Where I have to put the code, on AppDelegate?
Any suggestion are welcome.
Where I have to put the code, on AppDelegate?
Having the code in AppDelegate is not a very good idea. Instead you can have a viewController as splash screen. Set this viewController as your rootViewController. Do your initial web service call here and once you are done with it move to the first screen of your application.
How can I know if some data has been changed on server?
You will have to communicate to the server your version of the data. So set a version number for the data at the server side and keep track of it while downloading data. So if you pass the version number to server when you call the web service, the server can decide if there is any new data available. This way you can avoid downloading data that you have already downloaded.
where to store that information?
It depends on the data size that you want to store. And its security.
I think using database like Sqlite3 is a good option.
Hope this helps.
Where I have to put the code, on AppDelegate?
It depends on the behavior of your app as to where you decide to download the data. Typically if your app is supposed to display the latest data every time it goes to a new view then the data should be downloaded when that view is accessed. That way you will always be showing the latest available data to the user.
You would typically avoid putting too much into application: didFinishLaunchingWithOptions:, especially network connections as you dont know what kind of connection the user may have. If the connection takes an extended amount of time and application: didFinishLaunchingWithOptions: takes too long to return iOS will kill your application for taking too long to open which isn't good for the user experience at all.
How can I know if some data has been changed on server?
You will want to be passing either a last-modified timestamp or etag in the header of the response from the server. When you get the header response from the server you can than check against the previous last-modified data that you recieved or if the etag is different you know that the data has been changed. Doing it this way is a lot quicker than downloading all of the body to check a single parameter, if that parameter hasn't changed then you have just downloaded a bunch of data for nothing. I would discourage against versioning, versioning is more used for API changes rather than checking if data is out of date or not.
Storage Location?
It depends on the quantity of data you are going to be downloading, but I would advise using core data typically. The problem with storing data into a file and then saving that file is that every time you open the app you will have to break down that data into something useable before you can search through it etc. With core data you will have fully formed objects that you can search against using NSPredicate making everything a lot simpler to use in the long run.
If your just downloading a few settings then you could get away with something like a file or NSUserDefaults but if you are going to be displaying a list or collection of data to the user it's best to use core data.
How can I know if some data has been changed on server?
Use a variable version in your application and server also. Send application variable version with API and compere both version before downloading the data.
Where I have to put the code, on AppDelegate?
either can use applicationDidBecomeActive or didFinishLaunchingWithOptions depend on your requirement
- (void)applicationDidBecomeActive:(UIApplication *)application
OR
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Where to store that information
depending on the size of data and your requirement you can decide where to save the data
You can save data in UserDefault
You can save data as File in NSTemporaryDirectory / NSDocumentDirectory / NSLibraryDirectory. I think NSDocumentDirectory is fine for you.
You can save data in sqlite or CoreData

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

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